我正在创建一个新的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来实现此解决方案?
答案 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做类似的事情。
我希望它有所帮助。