我认为原因是因为我从未在身份验证服务器上设置受众(在 app.UseOpenIdConnectServer(...)),所以我认为它没有将受众信息写入令牌.所以我需要在身份验证服务器上设置一个受众(就像在 IdentityServer3 中所做的那样),但是我在选项对象上找不到可以让我这样做的属性.AspNet.Security.OpenIdConnect.Server 是否要求身份验证和资源位于同一服务器中?在组合 ClaimsPrincipal 时是否设置了受众?如果是,如何设置?我是否需要编写自定义受众验证器并将其连接到系统?(我当然希望答案是否定的.) 解决方案 AspNet.Security.OpenIdConnect.Server 是否要求身份验证和资源位于同一服务器中?不,您当然可以将这两个角色分开.正如您已经发现的那样,如果您不明确指定它,授权服务器将无法确定访问令牌的目的地/受众,该令牌是在没有aud 的情况下发布的OAuth2 承载中间件默认要求声明.解决这个问题很容易:只需在创建身份验证票证时调用 ticket.SetResources(resources),授权服务器将确切知道它应该使用哪个值(即资源服务器/API)添加 aud 声明.app.UseOpenIdConnectServer(options =>{//强制 OpenID Connect 服务器中间件使用 JWT 令牌//而不是默认使用的默认不透明/加密令牌格式.options.AccessTokenHandler = new JwtSecurityTokenHandler();});公共覆盖任务 HandleTokenRequest(HandleTokenRequestContext context){如果 (context.Request.IsPasswordGrantType()){var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);identity.AddClaim(OpenIdConnectConstants.Claims.Subject,唯一标识符");var 票证 = 新的 AuthenticationTicket(新的 ClaimsPrincipal(身份),新的身份验证属性(),context.Options.AuthenticationScheme);//使用资源服务器列表调用 SetResources//应为其颁发访问令牌.ticket.SetResources("resource_server_1");//使用您要授予的范围列表调用 SetScopes.ticket.SetScopes("profile", "offline_access");上下文.验证(票);}返回 Task.FromResult(0);}app.UseJwtBearerAuthentication(new JwtBearerOptions{自动身份验证 = 真,自动挑战 = 真,观众 = "resource_server_1",权限=http://localhost:61854"});The example on the AspNet.Security.OpenIdConnect.Server looks to me like both an auth and resource server. I would like to separate those. I have done so.At the auth server's Startup.Config, I have the following settings:app.UseOpenIdConnectServer(options => { options.AllowInsecureHttp = true; options.ApplicationCanDisplayErrors = true; options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme; options.Issuer = new System.Uri("http://localhost:61854"); // This auth server options.Provider = new AuthorizationProvider(); options.TokenEndpointPath = new PathString("/token"); options.UseCertificate(new X509Certificate2(env.ApplicationBasePath + "\mycertificate.pfx","mycertificate"));});I have an AuthorizationProvider written, but I don't think it's relevant to my current issue (but possibly relevant). At its GrantResourceOwnerCredentials override, I hard-code a claims principal so that it validates for every token request:public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification context){ var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.Name, "me"); identity.AddClaim(ClaimTypes.Email, "[email protected]"); var claimsPrincipal = new ClaimsPrincipal(identity); context.Validated(claimsPrincipal); return Task.FromResult<object>(null);}At the resource server, I have the following in its Startup.config:app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")), branch =>{ branch.UseOAuthBearerAuthentication(options => { options.Audience = "http://localhost:54408"; // This resource server, I believe. options.Authority = "http://localhost:61854"; // The auth server options.AutomaticAuthentication = true; });});On Fiddler, I ask for a token, and I get one:POST /token HTTP/1.1Host: localhost:61854Content-Type: application/x-www-form-urlencodedusername=admin&password=aaa000&grant_type=passwordSo now I use that access token to access a protected resource from the resource server:GET /api/values HTTP/1.1Host: localhost:54408Content-Type: application/json;charset=utf-8Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI.....I now get this error - Audience validation failed. Audiences: 'empty'. Did not match validationParameters.ValidAudience: 'http://localhost:54408' or validationParameters.ValidAudiences: 'null'.I think the reason why is because I never set an audience at the auth server (at app.UseOpenIdConnectServer(...)), so I don't think it wrote audience info to the token. So I need to set an audience at the auth server (as what is done in IdentityServer3), but I can't find a property on the options object that would let me do that.Does AspNet.Security.OpenIdConnect.Server require the auth and resource to be in the same server?Is setting the audience done when putting together the ClaimsPrincipal, and if so, how?Would I need to write a custom Audience validator and hook it up to the system? (I sure hope the answer to this is no.) 解决方案 Does AspNet.Security.OpenIdConnect.Server require the auth and resource to be in the same server?No, you can of course separate the two roles.As you've already figured out, if you don't explicitly specify it, the authorization server has no way to determine the destination/audience of an access token, which is issued without the aud claim required by default by the OAuth2 bearer middleware.Solving this issue is easy: just call ticket.SetResources(resources) when creating the authentication ticket and the authorization server will know exactly which value(s) (i.e resource servers/API) it should add in the aud claim(s).app.UseOpenIdConnectServer(options =>{ // Force the OpenID Connect server middleware to use JWT tokens // instead of the default opaque/encrypted token format used by default. options.AccessTokenHandler = new JwtSecurityTokenHandler();});public override Task HandleTokenRequest(HandleTokenRequestContext context){ if (context.Request.IsPasswordGrantType()) { var identity = new ClaimsIdentity(context.Options.AuthenticationScheme); identity.AddClaim(OpenIdConnectConstants.Claims.Subject, "unique identifier"); var ticket = new AuthenticationTicket( new ClaimsPrincipal(identity), new AuthenticationProperties(), context.Options.AuthenticationScheme); // Call SetResources with the list of resource servers // the access token should be issued for. ticket.SetResources("resource_server_1"); // Call SetScopes with the list of scopes you want to grant. ticket.SetScopes("profile", "offline_access"); context.Validate(ticket); } return Task.FromResult(0);}app.UseJwtBearerAuthentication(new JwtBearerOptions{ AutomaticAuthenticate = true, AutomaticChallenge = true, Audience = "resource_server_1", Authority = "http://localhost:61854"}); 这篇关于使用 AspNet.Security.OpenIdConnect 分离身份验证和资源服务器 - 观众?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-06 11:18