在具有asp.net身份的身份服务器4中实现角色 [英] implementing roles in identity server 4 with asp.net identity

查看:100
本文介绍了在具有asp.net身份的身份服务器4中实现角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用身份服务器4作为令牌服务的asp.net MVC应用程序.我也有一个API,其中包含一些安全资源.我想为api实现角色(授权).我想确保只有具有有效角色的授权资源才能访问api端点,否则将获得401(未授权错误).

I am working on an asp.net MVC application with identity server 4 as token service. I have an api as well which has some secure resources. I want to implement roles (Authorization) for api. I want to make sure that only an authorized resource with valid role can access an api end point otherwise get 401 (unauthorized error).

这是我的配置:

客户

         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")

                    }
                }

在服务器启动时,我添加了以下内容:

and in server startup i added this:

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

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

在api启动中,我有这个:

in api startup, i have this:

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

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

in api controller, i have this:

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

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

in MVC client startup, i have this:

 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:

I am trying to call the api like this:

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属性

I get access token but when call is made to api (identity/get), I get 302 error Forbidden (in chrome network it shows 500 internal server error). If I change API Authorize attribute from

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

收件人(无角色):

 [Authorize]
        public IActionResult Get()

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

it works and I get data from api in mvc app. How can I apply roles in this code.

请提出建议.

推荐答案

首先,您需要在OpenIdConnectOptions()中请求"API"作用域.

First, you need to request "API" scope in your OpenIdConnectOptions().

oidcOptions.Scope.Add("API");

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

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

Then you need to check if the role claim is included in the claims list available to your API controler(don't apply the roles filter in authorize attribute yet. Put a debug point inside controller method and expand User property). Check if the type of the role claim you received(listed in Claims Collection) matches User.Identity.RoleClaimType property

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

If the role claim type you have and User.Identity.RoleClaimType doesn't match, authorize attribute with roles filter won't work. You can set the correct RoleClaimType in IdentityServerAuthenticationOptions() like follows

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

这篇关于在具有asp.net身份的身份服务器4中实现角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆