为 ASP.NET Identity 2.0 连接 OAUTH 时如何从数据库中提取用户角色?
How to pull user roles from database when wiring up OAUTH for ASP.NET Identity 2.0?
我正在开发一些 Web API,并负责使用 ASP.NET Identity 2.0 向某些端点添加基于角色的授权。
我已经创建了一个基于 API 的管理结构来管理用户和角色,并且在尝试使用 OAUTH Bearer 令牌实施 authorization/authentication 时遇到了障碍。
(注意我读到 JWT 更好用并且可以更简单地提供用户数据,但要求是普通 OAUTH)
至于这里的代码是我到目前为止的代码,包括症结所在:
Startup.cs:
private static void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context, user manager and role manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
// Create the options for the token authorization
var oauthAuthorizationServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(oauthAuthorizationServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
SimpleAuthorizationServerProvider.cs:
public sealed class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// We are not validating clients at this point, simply "resource owners" i.e. user / pass combos
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (var repo = new AuthorizationRepository())
{
var user = repo.FindUser(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
}
// How do you pull the user data (including roles) from the database here, and place into a claim for API consumption??
}
}
我在网上找到的是以下内容,但这只会为用户(或角色列表)创建一个默认角色:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("sub", context.UserName));
context.Validated(identity);
上面的代码是一个问题,因为它会验证用户,然后在生成的令牌中为每个用户分配管理员角色!
如有任何帮助,我们将不胜感激,感谢您的帮助!
问题是您没有从 ApplicationUserManager
设置声明,这可以为您完成很多繁重的工作。此外,您只是设置了一个通用的 ClaimsIdentity
,正如您已经指出的那样,它将始终 return 所有用户的同一组角色。
在GrantResourceOwnerCredentials()
中,你要做的是:
//
// Get an instance of the ApplicationUserManager that you've already registered
// with OWIN
//
var mgr = context.OwinContext.GetUserManager<ApplicationUserManager>();
//
// Have the ApplicationUserManager build your ClaimsIdentity instead
//
var identity = await mgr.CreateIdentityAsync(user,
context.Options.AuthenticationType);
//
// Then here, you could add other application-specific claims if you wanted to.
我正在开发一些 Web API,并负责使用 ASP.NET Identity 2.0 向某些端点添加基于角色的授权。
我已经创建了一个基于 API 的管理结构来管理用户和角色,并且在尝试使用 OAUTH Bearer 令牌实施 authorization/authentication 时遇到了障碍。
(注意我读到 JWT 更好用并且可以更简单地提供用户数据,但要求是普通 OAUTH)
至于这里的代码是我到目前为止的代码,包括症结所在:
Startup.cs:
private static void ConfigureOAuthTokenGeneration(IAppBuilder app)
{
// Configure the db context, user manager and role manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
// Create the options for the token authorization
var oauthAuthorizationServerOptions = new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(1),
Provider = new SimpleAuthorizationServerProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(oauthAuthorizationServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
SimpleAuthorizationServerProvider.cs:
public sealed class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
// We are not validating clients at this point, simply "resource owners" i.e. user / pass combos
context.Validated();
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
using (var repo = new AuthorizationRepository())
{
var user = repo.FindUser(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
}
// How do you pull the user data (including roles) from the database here, and place into a claim for API consumption??
}
}
我在网上找到的是以下内容,但这只会为用户(或角色列表)创建一个默认角色:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
identity.AddClaim(new Claim("sub", context.UserName));
context.Validated(identity);
上面的代码是一个问题,因为它会验证用户,然后在生成的令牌中为每个用户分配管理员角色!
如有任何帮助,我们将不胜感激,感谢您的帮助!
问题是您没有从 ApplicationUserManager
设置声明,这可以为您完成很多繁重的工作。此外,您只是设置了一个通用的 ClaimsIdentity
,正如您已经指出的那样,它将始终 return 所有用户的同一组角色。
在GrantResourceOwnerCredentials()
中,你要做的是:
//
// Get an instance of the ApplicationUserManager that you've already registered
// with OWIN
//
var mgr = context.OwinContext.GetUserManager<ApplicationUserManager>();
//
// Have the ApplicationUserManager build your ClaimsIdentity instead
//
var identity = await mgr.CreateIdentityAsync(user,
context.Options.AuthenticationType);
//
// Then here, you could add other application-specific claims if you wanted to.