ADFS 2019:如何为客户端-服务器应用组添加自定义声明?
解决ADFS 2019中客户端-服务器应用的角色声明问题
我之前刚好在Angular+.NET Core的项目里踩过这个令牌缺角色的坑,给你一步步拆解怎么配置ADFS,满足后端[Authorize(Roles="Admin")]的授权需求:
1. 在ADFS 2019中为客户端-服务器应用添加自定义声明
核心是给你的.NET Core后端对应的信赖方信任配置颁发转换规则,让ADFS在发给后端的令牌里带上角色信息:
- 打开ADFS管理控制台,展开左侧的「应用程序组」,找到你的目标应用组,右键选「编辑应用程序组」。
- 在弹出窗口里,选中列表中的Web应用(对应.NET Core后端的信赖方条目),点击「编辑」。
- 切换到「颁发转换规则」标签页,点「添加规则」。
- 选合适的规则模板:
- 如果角色来自Active Directory用户组,选「发送LDAP属性作为声明」:
- 给规则起个好认的名字,比如「映射AD组到Role声明」
- 属性存储选「Active Directory」
- LDAP属性列选「令牌组-非限定名称」,传出声明类型选「角色」(对应默认URI:
http://schemas.microsoft.com/ws/2008/06/identity/claims/role,这是.NET默认识别的角色声明类型) - 点「完成」,再点「应用」保存配置。
- 如果需要自定义静态声明或复杂逻辑,选「发送自定义声明」,用ADFS规则语言编写,比如给特定用户加Admin角色:
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Value == "DOMAIN\\john.doe"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Value = "Admin");
- 如果角色来自Active Directory用户组,选「发送LDAP属性作为声明」:
2. 为「Web browser accessing a web application - Client-Server application」类型的应用组添加令牌自定义声明
这种应用组包含两个核心组件:Web应用(后端信赖方)和公共客户端(Angular前端)。要让后端授权生效,重点配置Web应用的规则;如果前端也需要角色信息,同步配置客户端规则即可:
配置Web应用(后端信赖方)的声明规则
直接重复第一部分的步骤,给应用组里的Web应用条目添加角色声明规则——这是[Authorize(Roles="Admin")]能生效的关键。
配置公共客户端(Angular前端)的声明规则(可选)
如果前端需要用角色做路由权限控制,给客户端也加对应规则:
- 在应用组编辑窗口中,选中公共客户端条目,点击「编辑」。
- 切换到「颁发转换规则」标签页,点「添加规则」,按第一部分的方法添加角色声明规则。
- 同时确保Angular的认证请求里包含正确的scope,比如
openid profile roles,ADFS才会把角色声明放进ID Token或Access Token。
.NET Core后端的声明映射配置
最后别忘了在后端配置里正确映射ADFS的声明,让.NET能识别出角色:
在Program.cs(或Startup.cs)的认证配置中添加:
builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme; options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie() .AddOpenIdConnect(options => { // 你的ADFS基础配置(Authority, ClientId, ClientSecret等) options.Authority = "https://your-adfs-server/adfs"; options.ClientId = "your-client-id"; options.ClientSecret = "your-client-secret"; options.ResponseType = "code"; // 映射Role声明 options.ClaimActions.MapJsonKey(ClaimTypes.Role, "role"); options.TokenValidationParameters = new TokenValidationParameters { RoleClaimType = ClaimTypes.Role }; });
验证配置是否生效
配置完后,用JWT解析工具(本地的解码器就行)解析后端收到的Access Token,看看有没有role声明,以及对应的角色值是否正确。如果一切正常,[Authorize(Roles="Admin")]就能正常拦截非Admin角色的请求了。
内容的提问来源于stack exchange,提问作者Bogdan B
相关产品推荐
相关产品推荐

