加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-web-api – 使用带有ASP.Net标识的Autofac将Application

发布时间:2020-12-16 03:49:22 所属栏目:asp.Net 来源:网络整理
导读:我正在使用ASP.Net Identity并希望通过以下文章将ApplicationUserManager服务添加到我的所有自定义控制器: How to plug my Autofac container into ASP. NET Identity 2.1 这在我的控制器中完美运行,但是当我尝试通过在我的API上调用localhost:xxxx / toke
我正在使用ASP.Net Identity并希望通过以下文章将ApplicationUserManager服务添加到我的所有自定义控制器: How to plug my Autofac container into ASP. NET Identity 2.1

这在我的控制器中完美运行,但是当我尝试通过在我的API上调用localhost:xxxx / token来创建令牌时.下面是调用的方法,但context.OwinContext.GetUserManager返回null.

我已经尝试将ApplicationUserManager注入到ApplicationOAuthProvider中,但是无法成功.你能指点我正确的方向吗?

编辑:10/15

好的,所以我已经进一步了,但我仍然卡住了.我能够使用以下内容初始化类:

var x = new DatabaseContext();
    var store = new UserStore<ApplicationUser>(x);
    var options = new IdentityFactoryOptions<ApplicationUserManager>()
    {
        DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationName")
    };

    builder.Register<DatabaseContext>(c => x);
    builder.Register<UserStore<ApplicationUser>>(c => store).AsImplementedInterfaces();
    builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => options);
    builder.RegisterType<ApplicationUserManager>();

    builder.Register<ApplicationOAuthProvider>(c => new ApplicationOAuthProvider("self",new ApplicationUserManager(store,options))).As<IOAuthAuthorizationServerProvider>();

这允许我将ApplicationUserManager传递给我的ApplicationOAuthProvider的构造函数.在Startup.Auth配置中,我使用以下内容初始化Provider:

OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),Provider = (IOAuthAuthorizationServerProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)),AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),AllowInsecureHttp = true
        };

这让我更接近解决方案,但仍有两个问题.

第一种是当我在API上调用/ token时,userManager.FindAsync(context.UserName,context.Password)返回空值,但userManager.FindByEmailAsync(context.UserName)返回正确的用户.我最初的想法是密码错误,但我确定它与我注册的密码相同.

第二个问题,如果我在我的AccountController上调用register,然后调用/ token,我得到一个无法访问已处置的对象.对象名称:’UserStore’错误.所以我认为这意味着我没有在我的Bootstrapper文件中正确初始化ApplicationOAuthProvider.

任何指导将不胜感激.谢谢!

解决方法

我终于找到了解决方案
第一个解决方
第一:更改你的bootstrap autofac类
你应该添加singleInstance();避免Per-Request Dependencies错误[没有标记匹配的范围’AutofacWebRequest’]

builder.RegisterType<DatabaseContext>().AsSelf().SingleInstance();
   builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });
   builder.RegisterType<ApplicationUserManager>().AsSelf().SingleInstance();
   // to resolve applicationUserManager  
   builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().SingleInstance();
   builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().SingleInstance();
   builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

第二:在Startup.cs中
将删除GlobalConfiguration.configuration.DependencyResolver,因为它总是给null.所以我将使用autofac容器解析器但应该从lifetimescope使用它,这个容器从你的bootstrap autofac配置方法返回

OAuthOptions = new OAuthAuthorizationServerOptions
    {
        TokenEndpointPath = new PathString("/Token"),Provider = container.BeginLifetimeScope().Resolve<IOAuthAuthorizationServerProvider>(),AllowInsecureHttp = true
    };

第三:在你的ApplicationOAuthProvider类中将添加构造函数取applicationUserManager作为参数

这个修复我的null错误后两天谷歌搜索,无法找到答案,希望它有所帮助.

第二个解决方案:因为SingleInstance()不适合企业应用程序,所以你可以使用InstancePerRequest();对于所有registerTypes

builder.RegisterType<DatabaseContext>().AsSelf().InstancePerRequest();
   builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });
   builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
   // to resolve applicationUserManager  
   builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().InstancePerRequest();
   builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().InstancePerRequest();
   builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

在Startup.cs中

OAuthOptions = new OAuthAuthorizationServerOptions
    {
        TokenEndpointPath = new PathString("/Token"),// will instantiate new one to avoid Single Instance for resolving
       Provider = new CustomOAuthProvider(new ApplicationUserManager(new UserStore<Entities.ApplicationUser>(new DataContext()),AllowInsecureHttp = true
    };

CustomOAuthProvider类

using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;

public class CustomOAuthProvider:OAuthAuthorizationServerProvider
{
    private ApplicationUserManager _appUserManager;
    public CustomOAuthProvider(ApplicationUserManager appUserManager)
    {
        this._appUserManager = appUserManager;
    }



    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = "*";

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin",new[] { allowedOrigin });


        var userManager = new ApplicationUserManager(new    Microsoft.AspNet.Identity.EntityFramework.UserStore<AppUser>(new      Data.DataContext()),new IdentityFactoryOptions<ApplicationUserManager>(),new Data.Repositories.SettingRepository(new Data.Infrastructure.DbFactory()));

       AppUser user = await userManager.FindAsync(context.UserName,context.Password);

        if (user == null)
        {
            context.SetError("invalid_grant","Invalid username or password.");
            return;
        }
        if (!user.IsActive)
        {
            context.SetError("invalid_activation","Inactive account,contact support.");
            return;
        }

        if (!user.EmailConfirmed)
        {
            context.SetError("invalid_grant","User did not confirm email.");
            return;
        }


        ClaimsIdentity oAuthIdentity = await userManager.GenerateUserIdentityAsync(user,"JWT");

        AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity,null);
        context.Validated(ticket);

    }


    public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        if (context.ClientId == null)
        {
            context.Validated();

        }

        return Task.FromResult<object>(null);
    }



}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读