.NET Owin身份验证使用我自己的userRepository

时间:2017-05-08 21:32:52

标签: authentication oauth-2.0 token owin

我正在创建一个新的Web API,并使用OAuth2进行令牌身份验证,使用UnityResolver进行DI。此刻,我有一些关于如何使用我自己的userRepository来验证用户的问题。这两天我一直在阅读很多关于这个问题的解决方案,我主要发现的解决方案是实现IStoredUser,IUser ..对于这种情况,我认为会有更好的契合度。 这是我的代码:

 public class OAuthServerProvider : OAuthAuthorizationServerProvider
{
    IUserAccountService _userAccountService;

    public OAuthServerProvider(IUserAccountService userAccountService)
    {
        _userAccountService = userAccountService;
    }

    public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
    {
        context.Validated();
    }

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        var ipAddress = HttpContext.Current.Request.UserHostAddress;
        var userAgent = HttpContext.Current.Request.UserAgent;

        var user = await _userAccountService.GetUserByLogin(context.UserName, context.Password, 1, userAgent, ipAddress);

        if (user != null && context.UserName == user.email && context.Password == user.password)
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
            identity.AddClaim(new Claim("username", user.email));
            identity.AddClaim(new Claim(ClaimTypes.Name, user.firstName));
            context.Validated(identity);
        }
        else
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }
    }

}

你可以看到我正在使用IUserAccountService来验证我的数据库中是否存在用户通过调用存储过程和dapper来调用SP,在这部分我没关系。当我需要在我的Startup.cs

中实例化这个类时,会出现问题
public class Startup
{
    internal IUserAccountService _userAccountService;

    public void Configuration(IAppBuilder app)
    {             
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  

        var oAuthProvider = new OAuthServerProvider(_userAccountService);

        OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/api/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = oAuthProvider
        };
        app.UseOAuthAuthorizationServer(options);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);
    }
}

由于IUserAccountService,我将得到一个空对象引用,我试图将它注入启动类构造函数,但它不起作用。

您是否知道如何通过使用良好实践和DI来实现此解决方案?

1 个答案:

答案 0 :(得分:0)

您可能已将IUserAccountService定义为每个请求的生命周期范围。 这样,IUserAccountService在Web请求开始时被实例化。 启动oauth服务器时执行Startup.Configuration()方法,此时没有Web请求。

我遇到了类似的问题,但我使用Autofac并解决了从OwinContext获取Autofac生命周期范围的问题:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    ...
    // Get IUserService from AutofacLifetimeScope (e.g. 'AutofacWebRequest')
    var autofacLifetimeScope = OwinContextExtensions.GetAutofacLifetimeScope(context.OwinContext);
    var userService = autofacLifetimeScope.Resolve<IUserService>();
    ...
}

这样您就可以从Web请求生存期范围中获取IUserService实例。

我不知道你是否可以用Unity做类似的事情。

我希望它有所帮助。