IdentityServer4系列(05)【授权方式】

IdentityServer4系列(05)【授权方式】基于角色验证服务器用户 添加新的 claim newClaim JwtClaimType Role 管理员 publicclassT publicstatic TestUser Users newList TestUser newTestUser SubjectId Username alice Passwor TestUser TestUser

基于角色

验证服务器

  • 用户,添加新的claim: new Claim(JwtClaimTypes.Role, "管理员")
public class TestUsers { 
    public static List<TestUser> Users = new List<TestUser> { 
    new TestUser{ 
   SubjectId = "", Username = "alice", Password = "alice", Claims = { 
    new Claim(JwtClaimTypes.Name, "Alice Smith"), new Claim(JwtClaimTypes.GivenName, "Alice"), new Claim(JwtClaimTypes.FamilyName, "Smith"), new Claim(JwtClaimTypes.Email, ""), new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), new Claim(JwtClaimTypes.WebSite, "http://alice.com"), new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json), new Claim(JwtClaimTypes.Role, "管理员") } }, new TestUser{ 
   SubjectId = "", Username = "bob", Password = "bob", Claims = { 
    new Claim(JwtClaimTypes.Name, "Bob Smith"), new Claim(JwtClaimTypes.GivenName, "Bob"), new Claim(JwtClaimTypes.FamilyName, "Smith"), new Claim(JwtClaimTypes.Email, ""), new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean), new Claim(JwtClaimTypes.WebSite, "http://bob.com"), new Claim(JwtClaimTypes.Address, @"{ 'street_address': 'One Hacker Way', 'locality': 'Heidelberg', 'postal_code': 69118, 'country': 'Germany' }", IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json), new Claim("location", "somewhere"), new Claim(JwtClaimTypes.Role, "普通用户") } } }; } 
  • Config.cs, 添加一个IdentityResource, 添加一个scope
public static IEnumerable<IdentityResource> GetIdentityResources() { 
    return new IdentityResource[] { 
    new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Address(), new IdentityResources.Phone(), new IdentityResources.Email(), new IdentityResource("roles","角色", new List<string>{ 
    JwtClaimTypes.Role}) //这里的roles指scope }; } new Client { 
    ClientId = "hybrid client", ClientName = "ASP.NET Core Hybrid client", ClientSecrets= { 
    new Secret("hybrid_secret".Sha256())}, AllowedGrantTypes=GrantTypes.Hybrid, RedirectUris = { 
    "http://localhost:7000/signin-oidc" }, PostLogoutRedirectUris = { 
    "http://localhost:7000/signout-callback-oidc" }, AllowOfflineAccess = true, AlwaysIncludeUserClaimsInIdToken=true, AllowedScopes = { 
    "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Address, IdentityServerConstants.StandardScopes.Email, IdentityServerConstants.StandardScopes.Phone, "roles" } } 

web服务器

  • Startup.cs, 在cookies中配置授权失败的转向页,在OpenIdConnect中配置有关roles
services.AddAuthentication(options => { 
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { 
    options.AccessDeniedPath = "/Authorization/AccessDenied"; }) .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => { 
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.ClientId = "hybrid client"; options.ClientSecret = "hybrid_secret"; options.SaveTokens = true; options.ResponseType = "code id_token"; options.Scope.Clear(); options.Scope.Add("api1"); options.Scope.Add(OidcConstants.StandardScopes.OpenId); options.Scope.Add(OidcConstants.StandardScopes.Profile); options.Scope.Add(OidcConstants.StandardScopes.Email); options.Scope.Add(OidcConstants.StandardScopes.Phone); options.Scope.Add(OidcConstants.StandardScopes.Address); options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess); options.Scope.Add("roles"); //把一些被自动过滤掉的claim找回来 options.ClaimActions.Remove("nbf"); options.ClaimActions.Remove("amr"); options.ClaimActions.Remove("exp"); //删除一些不需要的claim options.ClaimActions.DeleteClaim("sid"); options.ClaimActions.DeleteClaim("sub"); options.ClaimActions.DeleteClaim("idp"); //有关用户的roles options.TokenValidationParameters = new TokenValidationParameters { 
    NameClaimType = JwtClaimTypes.Name, RoleClaimType = JwtClaimTypes.Role }; }); 
  • 在控制器中
[Authorize(Roles = "管理员,普通用户")] 

基于策略,将多个claim组合在一起

在Startup.cs中的services.AddAuthorization中配置策略

//配置策略 services.AddAuthorization(options => { 
    options.AddPolicy("SmithInSomewhere", builder => { 
    builder.RequireAuthenticatedUser(); builder.RequireClaim(JwtClaimTypes.FamilyName, "Smith"); //这里值可以有多个,逗号分隔 builder.RequireClaim("location", "somewhere"); //这个不是标准claim哦 }); }); 

这里自定义的claim叫做location,位于某个scope中,这个scope需要在services.AddAuthentication中加上。

services.AddAuthentication(options => { 
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { 
    options.AccessDeniedPath = "/Authorization/AccessDenied"; }) .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options => { 
    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.Authority = "http://localhost:5000"; options.RequireHttpsMetadata = false; options.ClientId = "hybrid client"; options.ClientSecret = "hybrid_secret"; options.SaveTokens = true; options.ResponseType = "code id_token"; options.Scope.Clear(); options.Scope.Add("api1"); options.Scope.Add(OidcConstants.StandardScopes.OpenId); options.Scope.Add(OidcConstants.StandardScopes.Profile); options.Scope.Add(OidcConstants.StandardScopes.Email); options.Scope.Add(OidcConstants.StandardScopes.Phone); options.Scope.Add(OidcConstants.StandardScopes.Address); options.Scope.Add(OidcConstants.StandardScopes.OfflineAccess); options.Scope.Add("roles"); options.Scope.Add("locations"); //把一些被自动过滤掉的claim找回来 options.ClaimActions.Remove("nbf"); options.ClaimActions.Remove("amr"); options.ClaimActions.Remove("exp"); //删除一些不需要的claim options.ClaimActions.DeleteClaim("sid"); options.ClaimActions.DeleteClaim("sub"); options.ClaimActions.DeleteClaim("idp"); //有关用户的roles options.TokenValidationParameters = new TokenValidationParameters { 
    NameClaimType = JwtClaimTypes.Name, RoleClaimType = JwtClaimTypes.Role }; }); 

以上的locations这个scope需要在验证服务器上设置。

public static IEnumerable<IdentityResource> GetIdentityResources() { 
    return new IdentityResource[] { 
    new IdentityResources.OpenId(), new IdentityResources.Profile(), new IdentityResources.Address(), new IdentityResources.Phone(), new IdentityResources.Email(), new IdentityResource("roles","角色", new List<string>{ 
    JwtClaimTypes.Role}), //这里的roles指scope new IdentityResource("locations","地点", new List<string>{ 
    "location"} ) }; } new Client { 
    ClientId = "hybrid client", ClientName = "ASP.NET Core Hybrid client", ClientSecrets= { 
    new Secret("hybrid_secret".Sha256())}, AllowedGrantTypes=GrantTypes.Hybrid, RedirectUris = { 
    "http://localhost:7000/signin-oidc" }, PostLogoutRedirectUris = { 
    "http://localhost:7000/signout-callback-oidc" }, AllowOfflineAccess = true, AlwaysIncludeUserClaimsInIdToken=true, AllowedScopes = { 
    "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Address, IdentityServerConstants.StandardScopes.Email, IdentityServerConstants.StandardScopes.Phone, "roles", "locations" } } 

更复杂的策略

  • 一个action可以有多个Policy作用
  • 一个Policy, 通过RequireAuthenticatedUser,RequireClaim, IAuthorizationRequirement生成,
  • 一个IAuthorizationRequirement中有多个AuthorizationHandler

首先需要实现IAuthorizationRequirement

public class SmithInSomewhereRequirement : IAuthorizationRequirement { 
    public SmithInSomewhereRequirement() { 
    } } 

其次需要一个AuthorizationHandler

 public class SmithInSomewhereHandler : AuthorizationHandler<SmithInSomewhereRequirement> { 
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SmithInSomewhereRequirement requirement) { 
    //var filterContext = context.Resource as AuthorizationFilterContext; //if(filterContext==null) //{ 
    // context.Fail(); // return Task.CompletedTask; //} var familyName = context.User.Claims.FirstOrDefault(c => c.Type == JwtClaimTypes.FamilyName)?.Value; var location = context.User.Claims.FirstOrDefault(t => t.Type == "location")?.Value; if(familyName == "Smith" && location == "somewhere" && context.User.Identity.IsAuthenticated) { 
    context.Succeed(requirement); return Task.CompletedTask; } context.Fail(); return Task.CompletedTask; } } 

最后在startup.cs中设置:

//配置策略 services.AddAuthorization(options => { 
    //options.AddPolicy("SmithInSomewhere", builder => { 
    // builder.RequireAuthenticatedUser(); // builder.RequireClaim(JwtClaimTypes.FamilyName, "Smith"); //这里值可以有多个,逗号分隔 // builder.RequireClaim("location", "somewhere"); //这个不是标准claim哦 //}); options.AddPolicy("SmithInSomewhere", builder => { 
    builder.AddRequirements(new SmithInSomewhereRequirement()); }); }); 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232591.html原文链接:https://javaforall.net

(0)
上一篇 2025年9月29日 下午2:01
下一篇 2025年9月29日 下午2:22


相关推荐

  • 腾讯楼下近千人排队安装,用户都在用OpenClaw做什么?

    腾讯楼下近千人排队安装,用户都在用OpenClaw做什么?

    2026年3月13日
    3
  • python爬虫基础及实例—代码经过实测

    python爬虫基础及实例—代码经过实测requests 模块发送 get post 请求 response requests get url response requests post url data 请求体的字典 response 的方法 response text 该方法经常会出现乱码 出现乱码使用 response encoding utf 8 response content decod

    2026年3月18日
    2
  • c中构造函数的作用_python中构造方法的作用

    c中构造函数的作用_python中构造方法的作用C#中构造函数的作用共同点:都是实例化对象,初始化数据的默认构造是说所有的类都从祖先object那继承了空参的构造方法,你不写与写空参构造都存在,而有参数的构造一般是自己写的,写就有不写就没有,它的作用和空参的一样,只是它里面可以有参数,给你个例子来说明吧有一个类Monitor它有属性Stringheight;StringwidthpublicMonitor(){}publ

    2025年10月1日
    5
  • win7 配置JDK环境变量

    win7 配置JDK环境变量第一步 安装 jdk 8u101 windows x64 exe 路径为默认路径 一直下一步直到完成安装 安装最好不要修改安装路径 防止自己找不到 第二步 设置环境变量 1 进入环境变量设置的方法 这里只针对 Windows7 计算机 右键 属性 高级系统设置 高级 环境变量 打开环境变量设置窗口 2 在下面的 系统环境变量 设置窗口中 点击 新建 建立 JAVA HOME

    2026年3月17日
    2
  • 服务器硬件基础知识

    服务器硬件基础知识服务器的概述计算机的硬件主要有主机和输入/输出设备。主机包括机箱,电源,主板,CPU(中央处理器),内存,显卡,声卡,网卡,硬盘,光驱等。输入/输出包括显示器,键盘,鼠标,音箱,摄像头,打印机和扫描仪等。服务器服务器是指在网络环境下运行相应的应用软件,为网上用户提供共享信息资源和各种服务的一直高性能计算机。服务器的选择:处理器性能,I/O性能,管理性,可靠性,扩展性。同样…

    2022年7月22日
    13
  • fasterrcnn详解_faster RCNN

    fasterrcnn详解_faster RCNNpaper:FasterR-CNN:TowardsReal-TimeObjectDetectionwithRegionProposalNetworks前言fasterrcnn是何凯明等大神在2015年提出目标检测算法,该算法在2015年的ILSVRV和COCO竞赛中获得多项第一。该算法在fastrcnn基础上提出了RPN候选框生成算法,使得目标检测速度大大提高。RCN…

    2022年10月5日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号