加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-identity – 使用asp.net身份在身份服务器4中实现角色

发布时间:2020-12-16 04:09:35 所属栏目:asp.Net 来源:网络整理
导读:我正在使用身份服务器4作为令牌服务的asp.net MVC应用程序.我有一个api,它有一些安全的资源.我想为api实现角色(授权).我想确保只有具有有效角色的授权资源才能访问api端点,否则会获得401(未经授权的错误). 这是我的配置: 客户 new Client() { ClientId = "m
我正在使用身份服务器4作为令牌服务的asp.net MVC应用程序.我有一个api,它有一些安全的资源.我想为api实现角色(授权).我想确保只有具有有效角色的授权资源才能访问api端点,否则会获得401(未经授权的错误).

这是我的配置:

客户

new Client()
            {
                ClientId = "mvcClient",ClientName = "MVC Client",AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,ClientSecrets = new List<Secret>()
                {
                    new Secret("secret".Sha256())
                },RequireConsent = false;

                // where to redirect to after login
                RedirectUris = { "http://localhost:5002/signin-oidc" },// where to redirect to after logout
                PostLogoutRedirectUris = { "http://localhost:5002" },AllowedScopes =
                {
                    StandardScopes.OpenId.Name,StandardScopes.Profile.Name,StandardScopes.OfflineAccess.Name,StandardScopes.Roles.Name,"API"
                }
            }

领域

return new List<Scope>()
            {
                StandardScopes.OpenId,// subject id
                StandardScopes.Profile,// first name,last name
                StandardScopes.OfflineAccess,// requesting refresh tokens for long lived API access
               StandardScopes.Roles,new Scope()
                {
                    Name = "API",Description = "API desc",Type = ScopeType.Resource,Emphasize = true,IncludeAllClaimsForUser = true,Claims = new List<ScopeClaim>
                    {
                        new ScopeClaim(ClaimTypes.Name),new ScopeClaim(ClaimTypes.Role)
                    }
                }
            };

用户

new InMemoryUser()
                {
                    Subject = "1",Username = "testuser",Password = "password",Claims = new List<Claim>()
                    {
                        new Claim("name","Alice"),new Claim("Website","http://alice.com"),new Claim(JwtClaimTypes.Role,"admin")

                    }
                }

在服务器启动中我添加了这个:

services.AddIdentityServer()
.AddTemporarySigningCredential()
.AddSigningCredential(CERT)
.AddInMemoryClients(Config.GetClients())
.AddInMemoryScopes(Config.GetScopes())
.AddInMemoryUsers(Config.GetUsers())

在api启动中,我有这个:

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
            {
                Authority = "http://localhost:5000",ScopeName = "NamfusAPI",RequireHttpsMetadata = false
            });

在api控制器中,我有这个:

[Authorize(Roles = "admin")]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new {c.Type,c.Value });
        }

在MVC客户端启动中,我有这个:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

 app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationScheme = "Cookies"
            });


            var oidcOptions = new OpenIdConnectOptions()
            {
                AuthenticationScheme = "oidc",SignInScheme = "Cookies",Authority = "http://localhost:5000",RequireHttpsMetadata = false,ClientId = "mvcClient",ClientSecret = "secret",SaveTokens = true,GetClaimsFromUserInfoEndpoint = true,ResponseType = "code id_token",// hybrid flow

            };


            oidcOptions.Scope.Clear();
            oidcOptions.Scope.Add("openid");
            oidcOptions.Scope.Add("profile");
            oidcOptions.Scope.Add("NamfusAPI");
            oidcOptions.Scope.Add("offline_access");
            oidcOptions.Scope.Add("roles");

我试图像这样调用api:

public async Task<IActionResult> CallApiUsingUserAccessToken()
        {
            var accessToken = await HttpContext.Authentication.GetTokenAsync("access_token");

            var client = new HttpClient();
            client.SetBearerToken(accessToken);
            var content = await client.GetStringAsync("http://localhost:5001/identity");

            ViewBag.Json = JArray.Parse(content).ToString();
            return View("json");
        }

我得到访问令牌但是当调用api(身份/获取)时,我得到302错误禁止(在chrome网络中它显示500内部服务器错误).如果我从中更改API Authorize属性

[Authorize(Roles = "admin")]
            public IActionResult Get()

到(没有角色):

[Authorize]
        public IActionResult Get()

它工作,我从mvc应用程序中的api获取数据.如何在此代码中应用角色.

请建议.

解决方法

首先,您需要在OpenIdConnectOptions()中请求“API”范围.
oidcOptions.Scope.Add("API");

要么

Scope = { "API","offline_access",..},

然后,您需要检查角色声明是否包含在API控制器可用的声明列表中(不要在authorize属性中应用角色过滤器.在控制器方法中放置一个调试点并展开User属性).检查您收到的角色声明的类型(在声明集合中列出)是否与User.Identity.RoleClaimType属性匹配

如果您拥有的角色声明类型与User.Identity.RoleClaimType不匹配,则使用角色过滤器的authorize属性将不起作用.您可以在IdentityServerAuthenticationOptions()中设置正确的RoleClaimType,如下所示

app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000",ScopeName = "API",RoleClaimType = ClaimTypes.Role,RequireHttpsMetadata = false
        });

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读