asp.net-mvc IdentityServer4 基于角色的授权
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40844310/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Role based authorization with IdentityServer4
提问by muhammad waqas
I am trying to implement "Role Based Authorization" using IdentityServer4 to give access to my API based on the user roles.
我正在尝试使用 IdentityServer4 实现“基于角色的授权”,以便根据用户角色访问我的 API。
For example , I want to have two roles for the user i.e. FreeUser and PaidUser and want to give access to the API through the Authorize Attribute using [Authorize(Roles = "FreeUser"))], Kindly help me that How can I achieve this.
例如,我想为用户提供两个角色,即 FreeUser 和 PaidUser,并希望使用 [Authorize(Roles = "FreeUser"))] 通过授权属性授予对 API 的访问权限,请帮助我如何实现这一点.
I have the following solution structure :
我有以下解决方案结构:
- IdentityServer
- WebApi
- Javascript Client
- 身份服务器
- 网络接口
- Javascript客户端
I have registered my Javascript client as follows:
我已按如下方式注册了我的 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
}
}
Scopes
范围
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
};
Users
用户
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
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();
}
Web Api controller
Web 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 Client app.jsHere I am trying to login the user through IdentityServer and make an API Request.
Javascript Client 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();
}
The Login flow works fine and I can login successfully, and I can receive the role in the access token.
登录流程工作正常,我可以成功登录,并且可以在访问令牌中接收角色。
When I make a request to the API by clicking the button (Call Api) then I get the following error..

采纳答案by rawel
Given that you have not provided config object for javascript client, I assume you have scope configured as follows.
鉴于您尚未为 javascript 客户端提供配置对象,我假设您的范围配置如下。
scope:"openid profile api1 role"
I believe that the main reason for your issue is that role claim is not included in your access token.
我相信您的问题的主要原因是角色声明未包含在您的访问令牌中。
Add role claim to api1 scope as follows to include it in the access token.
将角色声明添加到 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)
}
}
You can read my answer here for help debug the issue. implementing roles in identity server 4 with asp.net identity
您可以在此处阅读我的回答以帮助调试问题。 使用 asp.net 身份在身份服务器 4 中实现角色
The complete working solution is here. https://github.com/weliwita/IdentityServer4.Samples/tree/40844310
完整的工作解决方案在这里。 https://github.com/weliwita/IdentityServer4.Samples/tree/40844310
回答by adem caglin
Change new Claim("role","FreeUser")to new Claim(ClaimTypes.Role, "FreeUser")
更改new Claim("role","FreeUser")为new Claim(ClaimTypes.Role, "FreeUser")
Or create a policy like this:
或者创建一个这样的策略:
services.AddAuthorization(options =>
{
options.AddPolicy("FreeUser", policy => policy.RequireClaim("role", "FreeUser"));
});
and use it :
并使用它:
Authorize[(Policy = "FreeUser")]
回答by Mohammad Karimi
I wrote a sample on this post
我在这篇文章上写了一个样本
Identity Server 4: adding claims to access token
I have tested with Roles and claims also I can use [Authorize(Role="SuperAdmin, Admin")] in both client web app and API app.
我已经对角色和声明进行了测试,我也可以在客户端 Web 应用程序和 API 应用程序中使用 [Authorize(Role="SuperAdmin, Admin")]。

