IdentityServer4基于角色的授权
我正在尝试使用IdentityServer4实现“基于角色的授权”,以便根据用户角色授予我的API访问权限。IdentityServer4基于角色的授权
例如,我希望为用户提供两个角色,即FreeUser和PaidUser,并希望通过授权属性使用[Authorize(Roles =“FreeUser”))]访问API,请帮助我如何我可以做到这一点吗?
我有以下解决方案结构:
- IdentityServer
- 的WebAPI
- JavaScript客户端
我已经注册了我的JavaScript客户端如下:
new Client
{
ClientId = "js",
ClientName = "javascript client",
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser= true,
RedirectUris = {"http://localhost:5004/callback.html"},
PostLogoutRedirectUris = {"http://localhost:5004/index.html"},
AllowedCorsOrigins = {"http://localhost:5004"},
AllowedScopes =
{
StandardScopes.OpenId.Name,
StandardScopes.Profile.Name,
"api1",
"role",
StandardScopes.AllClaims.Name
}
}
个作用域
return new List<Scope>
{
StandardScopes.OpenId,
StandardScopes.Profile,
new Scope
{
Name = "api1",
Description = "My API"
},
new Scope
{
Enabled = true,
Name = "role",
DisplayName = "Role(s)",
Description = "roles of user",
Type = ScopeType.Identity,
Claims = new List<ScopeClaim>
{
new ScopeClaim("role",false)
}
},
StandardScopes.AllClaims
};
用户
return new List<InMemoryUser>
{
new InMemoryUser
{
Subject = "1",
Username = "alice",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Alice"),
new Claim("website", "https://alice.com"),
new Claim("role","FreeUser")
}
},
new InMemoryUser
{
Subject = "2",
Username = "bob",
Password = "password",
Claims = new List<Claim>
{
new Claim("name", "Bob"),
new Claim("website", "https://bob.com"),
new Claim("role","PaidUser")
}
}
};
的WebAPI Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
app.UseCors("default");
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = "http://localhost:5000",
ScopeName = "api1",
// AdditionalScopes = new List<string> { "openid","profile", "role" },
RequireHttpsMetadata = false
});
app.UseMvc();
}
网络API控制器
namespace Api.Controllers
{
[Route("[controller]")]
public class IdentityController : ControllerBase
{
[HttpGet]
[Authorize(Roles = "PaidUser")]
public IActionResult Get()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
[Authorize(Roles = "FreeUser")]
[HttpGet]
[Route("getfree")]
public IActionResult GetFreeUser()
{
return new JsonResult(from c in User.Claims select new { c.Type, c.Value });
}
}
}
JavaScript客户端app.js 在这里,我试图登录通过IdentityServer用户,使API请求。
var mgr = new Oidc.UserManager(config);
mgr.getUser().then(function (user) {
if (user) {
log("User logged in", user.profile);
} else {
log("User is not logged in.");
}
});
function login() {
mgr.signinRedirect();
}
function api() {
mgr.getUser().then(function (user) {
var url = "http://localhost:5001/identity/getfree";
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = function() {
log(xhr.status, JSON.parse(xhr.responseText));
};
xhr.setRequestHeader("Authorization", "Bearer " + user.access_token);
xhr.send();
});
}
function logout() {
mgr.signoutRedirect();
}
登录流程正常,我可以成功登录,并且我可以接收访问令牌中的角色。
鉴于您没有提供JavaScript客户端的配置对象,我假设您的作用域配置如下。
scope:"openid profile api1 role"
我相信您的问题的主要原因是您的访问令牌中没有包含角色声明。
将角色声明添加到api1范围,如下所示将其包含在访问令牌中。
new Scope
{
Name = "api1",
DisplayName = "API1 access",
Description = "My API",
Type = ScopeType.Resource,
IncludeAllClaimsForUser = true,
Claims = new List<ScopeClaim>
{
new ScopeClaim(ClaimTypes.Name),
new ScopeClaim(ClaimTypes.Role)
}
}
你可以在这里阅读我的答案以帮助调试问题。 implementing roles in identity server 4 with asp.net identity
完整的工作解决方案就在这里。 https://github.com/weliwita/IdentityServer4.Samples/tree/40844310
变化new Claim("role","FreeUser")
到new Claim(ClaimTypes.Role, "FreeUser")
或者创建一个像这样的政策:
services.AddAuthorization(options =>
{
options.AddPolicy("FreeUser", policy => policy.RequireClaim("role", "FreeUser"));
});
和我们电子邮件:
Authorize[(Policy = "FreeUser")]
感谢您的回复,我已经尝试了两种方法,但结果相同,如果在创建API请求时添加策略,则会向API发出两个请求,第一个请求会显示204 [无内容]状态代码,而第二个失败与403 ..在索赔的情况下,结果是一样的403 ..有我失踪的东西?.. –
我写了一个样品上此篇
Identity Server 4: adding claims to access token
我与角色和权利要求书测试也我可以使用[授权(角色=“超级管理员,管理员”)]在两个客户端的web应用程序和API应用程序。
伟大..现在工作正常..我不能相信我是如何忘记将其添加到范围..谢谢无论如何.. –
@muhammadwaqas我认为你应该接受答案 – Learner