IdentityServer:检查 OpenId Connect 中的身份验证策略中是不是存在范围
Posted
技术标签:
【中文标题】IdentityServer:检查 OpenId Connect 中的身份验证策略中是不是存在范围【英文标题】:IdentityServer: Check if scopes present in a policy for authentication in OpenId ConnectIdentityServer:检查 OpenId Connect 中的身份验证策略中是否存在范围 【发布时间】:2021-09-27 05:22:38 【问题描述】:有2个项目:
1. IdentityServer project
2. Client Project
在我的客户项目中,我有一个具有基于策略的身份验证的控制器:
[ApiController]
[Route("[controller]")]
[Authorize(Policy ="SomePolicy")]
public class BankController : ControllerBase
...
在客户端项目的 Startup.cs 中,我添加了策略身份验证代码,该代码表示令牌应包含值为“fullaccess”的“范围”。见以下代码:
services.AddAuthorization(options =>
options.AddPolicy("SomePolicy", policy =>
policy.RequireClaim("scope", "fullaccess");
);
);
“完全访问”是在 IdentityServer 项目的 appsetting.json 上定义的 ApiScope。
"IdentityServerSettings":
"ApiScopes": [
"Name": "fullaccess"
],
...
代码在邮递员测试中运行良好。
现在我通过添加行 options.Scope.Add("fullaccess");
在我的客户项目上的 OIDC 上添加了这个范围,请参见下面的代码。
.AddOpenIdConnect("oidc", options =>
options.Authority = "https://localhost:5001";
options.ClientId = "postman";
options.ResponseType = "code";
//adding fullaccess scope
options.Scope.Add("fullaccess");
options.SaveTokens = true;
);
现在我尝试在浏览器上输入 BankController。这个控制器受我创建的这个策略的保护。会发生以下情况:
-
我被重定向到 IdentityServer 登录页面。
然后我登录,在此 IdentityServer 将我重定向回 BankController 之后。
现在代替银行控制器显示内容。我被重定向到 AccessDenied,因为“fullaccess”范围似乎不存在,但为什么呢?
控制台显示如下错误:
Authorization failed. These requirements were not met:
ClaimsAuthorizationRequirement:Claim.Type=scope and Claim.Value is one of the following values: (fullaccess)
如何解决?
【问题讨论】:
控制台或浏览器是否有错误信息? @TinyWang 没有错误。 嗨,@yogihosting,请允许我在下面发布我的编程步骤,因为我们找不到错误。希望它可以帮助您集成身份服务器4 :) 有进展吗?还有什么问题还是根本没用? @TinyWang 没有进展。我在问题上添加了更多内容(以及控制台上的错误)。请看一看。 【参考方案1】:我想我可以在这里分享我的集成步骤来帮助您解决问题。
点击这里查看related blog。
首先,我创建了一个 asp.net core 3.1 mvc 项目,并安装了这些包:
<ItemGroup>
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.17" />
</ItemGroup>
然后添加一个名为 Config.cs 的文件,请注意在我的项目中,https 的默认端口是 5001,请参阅launchSetting.json:
using IdentityModel;
using IdentityServer4;
using IdentityServer4.Models;
using IdentityServer4.Test;
using System.Collections.Generic;
using System.Security.Claims;
namespace WebApplication1
public class Config
public static IEnumerable<IdentityResource> GetIdentityResources()
return new List<IdentityResource>
new IdentityResources.OpenId(),
new IdentityResources.Profile(),
new IdentityResource
Name = "role",
UserClaims = new List<string> "role"
;
public static IEnumerable<ApiScope> GetApiScopes()
return new List<ApiScope>
new ApiScope("api1.read", "Read Access to API #1"),
new ApiScope("api1.write", "Write Access to API #1")
;
public static IEnumerable<ApiResource> GetApiResources()
return new List<ApiResource>
new ApiResource
Name = "api1",
DisplayName = "API #1",
Description = "Allow the application to access API #1 on your behalf",
Scopes = new List<string> "api1.read", "api1.write",
ApiSecrets = new List<Secret> new Secret("ScopeSecret".Sha256()),
UserClaims = new List<string> "role"
;
public static IEnumerable<Client> GetClients()
return new List<Client>
// other clients omitted...
new Client
ClientId = "oidcClient",
ClientName = "Example Client Application",
ClientSecrets = new List<Secret> new Secret("SuperSecretPassword".Sha256()), // change me!
AllowedGrantTypes = GrantTypes.Code,
RedirectUris = new List<string> "https://localhost:5001/signin-oidc",
AllowedScopes = new List<string>
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
"role",
"api1.read"
,
RequirePkce = true,
AllowPlainTextPkce = false
,
new Client
ClientId = "oauthClient",
ClientName = "Example client application using client credentials",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = new List<Secret> new Secret("SuperSecretPassword".Sha256()), // change me!
AllowedScopes = new List<string> "api1.read"
;
public static List<TestUser> GetUsers()
return new List<TestUser>
new TestUser
SubjectId = "5BE86359-073C-434B-AD2D-A3932222DABE",
Username = "tiny",
Password = "111",
Claims = new List<Claim>
new Claim(JwtClaimTypes.Email, "tiny@gmail.com"),
new Claim(JwtClaimTypes.Role, "admin")
;
接下来,我们可以使用 powershell 运行命令在我们的项目中为登录部分安装默认的identity server 4 ui。因为它还会提供一个 HomeController.cs,所以我们可以在创建项目时重命名或删除原来的 HomeController。进入项目根目录,打开powershell运行:
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/main/getmain.ps1'))
然后我们需要修改startup.cs,这是我的文件:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Threading.Tasks;
namespace WebApplication1
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryApiScopes(Config.GetApiScopes())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
services.AddControllersWithViews();
//If we only need to enable the token validation for api, use the code commented below
//services.AddAuthentication("Bearer")
//.AddIdentityServerAuthentication("Bearer", options =>
//
// options.ApiName = "api1";
// options.Authority = "https://localhost:5001";
//);
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
)
.AddCookie("cookie")
.AddOpenIdConnect("oidc", options =>
options.Authority = "https://localhost:5001";
options.ClientId = "oidcClient";
options.ClientSecret = "SuperSecretPassword";
options.ResponseType = "code";
options.UsePkce = true;
options.ResponseMode = "query";
options.CallbackPath = "/signin-oidc"; // default redirect URI
// options.Scope.Add("oidc"); // default scope
// options.Scope.Add("profile"); // default scope
options.Scope.Add("api1.read");
options.SaveTokens = true;
);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllerRoute(
name: "default",
pattern: "controller=Home/action=Index/id?");
);
最后,让我们在 HomeController 中注释 [AllowAnonymous]
属性并为隐私页面添加一个操作:
[Authorize]
public IActionResult Privacy() => View();
我们还可以添加一个新的控制器,使其像 api 一样工作,并在该控制器上添加 [Authorize]
,例如
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1.Controllers
[Authorize]
public class HelloController : Controller
public string Index()
return "hello world";
然后启动程序,我们可以直接看到主页,但是如果我们访问https://localhost:5001/hello/index
,https://localhost:5001/home/privacy
,它会重定向到一个登录页面,登录后(用户名和密码在config.cs中定义) 我们可以看到私人页面或响应消息。
【讨论】:
不,我的授权属性是 [Authorize(Policy ="SomePolicy")] 而不是 [Authorize]以上是关于IdentityServer:检查 OpenId Connect 中的身份验证策略中是不是存在范围的主要内容,如果未能解决你的问题,请参考以下文章
IdentityServer4- 使用OpenID Connect添加用户身份验证(implicit)
IdentityServer3——入门教程:.NET开源OpenID Connect 和OAuth解决方案IdentityServer v3 术语
IdentityServer4 well-known/openid-configuration
IDX20803:无法从以下位置获取配置:“https://localhost/IdentityServer/Core/.well-known/openid-configuration”