C# 使用asp.net标识在identity server 4中实现角色

C# 使用asp.net标识在identity server 4中实现角色,c#,asp.net-identity,identityserver4,asp.net-core-1.0,C#,Asp.net Identity,Identityserver4,Asp.net Core 1.0,我正在使用identity server 4作为令牌服务开发一个asp.net MVC应用程序。我也有一个api,它有一些安全的资源。我想为api实现角色(授权)。我希望确保只有具有有效角色的授权资源才能访问api端点,否则将获得401(未授权错误) 以下是我的配置: 客户端 new Client() { ClientId = "mvcClient", ClientName = "MVC C

我正在使用identity server 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"
                }
            }
在api控制器中,我有:

  app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
            {
                Authority = "http://localhost:5000",
                ScopeName = "NamfusAPI",
                RequireHttpsMetadata = false
            });
 [Authorize(Roles = "admin")]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new {c.Type, c.Value });
        }
 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");
在MVC客户端启动中,我有以下几点:

  app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
            {
                Authority = "http://localhost:5000",
                ScopeName = "NamfusAPI",
                RequireHttpsMetadata = false
            });
 [Authorize(Roles = "admin")]
        public IActionResult Get()
        {
            return new JsonResult(from c in User.Claims select new {c.Type, c.Value });
        }
 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");
        } 
至(无角色):

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


请建议。

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

然后,您需要检查角色声明是否包含在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
        });

罗威尔感谢您的回复。当我尝试RoleClaimType=ClaimTypes时,我发现RoleClaimType不可用。Role,在mvc客户端中,像这样
code
var oidcOptions=new OpenIdConnectOptions(){AuthenticationScheme=“oidc”,Signenscheme=“Cookies”,Authority=“”,RequireHttpsMetadata=false,GetClaimsFromUserInfoEndpoint=true,RoleClaimType=ClaimTypes.Role,}<代码>代码应将其添加到Api中。要识别ServerAuthenticationOptions,我看到controller中的User.Claims属性为null,其中identity中的as RoleCalimtype具有如上所示的相同值。抱歉,我不知道Claims集合如何为null。如果索赔不可用,则授权筛选器将不起作用。检查API中的配置。或者从Identity Server存储库中一个干净的工作示例开始。它不会显示我为内存用户配置的名称等创建的用户声明。非常确定您不应该同时执行
AddTemporarySigningCredential()
AddSigningCredential(cert)
oidcOptions.Scope.Add("API");
Scope = { "API", "offline_access",..},
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
        {
            Authority = "http://localhost:5000",
            ScopeName = "API",
            RoleClaimType = ClaimTypes.Role,
            RequireHttpsMetadata = false
        });