使用 AspNet.Security.OpenIdConnect 将 Auth 和资源服务器分开 - 观众?
Separating Auth and Resource Servers with AspNet.Security.OpenIdConnect - the Audience?
AspNet.Security.OpenIdConnect.Server 上的示例在我看来既像身份验证服务器又像资源服务器。我想把它们分开。我已经这样做了。
在认证服务器的 Startup.Config,我有以下设置:
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"));
});
我写了一个 AuthorizationProvider,但我认为它与我当前的问题无关(但可能相关)。在其 GrantResourceOwnerCredentials 覆盖中,我硬编码了一个声明主体,以便它验证每个令牌请求:
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification context)
{
var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
identity.AddClaim(ClaimTypes.Name, "me");
identity.AddClaim(ClaimTypes.Email, "me@gmail.com");
var claimsPrincipal = new ClaimsPrincipal(identity);
context.Validated(claimsPrincipal);
return Task.FromResult<object>(null);
}
在资源服务器上,我在其 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;
});
});
在 Fiddler 上,我请求一个令牌,我得到了一个:
POST /token HTTP/1.1
Host: localhost:61854
Content-Type: application/x-www-form-urlencoded
username=admin&password=aaa000&grant_type=password
所以现在我使用该访问令牌从资源服务器访问受保护的资源:
GET /api/values HTTP/1.1
Host: localhost:54408
Content-Type: application/json;charset=utf-8
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI.....
我现在收到此错误 - 受众验证失败。听众:'empty'。不匹配 validationParameters.ValidAudience: 'http://localhost:54408' 或 validationParameters.ValidAudiences: 'null'.
我认为原因是因为我从未在身份验证服务器(在 app.UseOpenIdConnectServer(...))上设置观众,所以我认为它没有将观众信息写入令牌。所以我需要在 auth 服务器上设置一个观众(就像在 IdentityServer3 中所做的那样),但是我在选项对象上找不到 属性 让我这样做。
AspNet.Security.OpenIdConnect.Server 是否要求授权和资源在同一台服务器上?
是否在将 ClaimsPrincipal 放在一起时完成设置受众,如果是,如何设置?
我是否需要编写自定义受众验证程序并将其连接到系统? (我当然希望答案是否定的。)
Does AspNet.Security.OpenIdConnect.Server require the auth and resource to be in the same server?
不,你当然可以把这两个角色分开。
如您所知,如果不明确指定,授权服务器无法确定访问令牌的 destination/audience,而访问令牌是在没有 [=11= 的情况下颁发的] OAuth2 承载中间件默认要求声明。
解决这个问题很简单:只需在创建身份验证票据时调用 ticket.SetResources(resources)
,授权服务器就会确切知道应该在 aud
索赔。
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.Server 上的示例在我看来既像身份验证服务器又像资源服务器。我想把它们分开。我已经这样做了。
在认证服务器的 Startup.Config,我有以下设置:
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"));
});
我写了一个 AuthorizationProvider,但我认为它与我当前的问题无关(但可能相关)。在其 GrantResourceOwnerCredentials 覆盖中,我硬编码了一个声明主体,以便它验证每个令牌请求:
public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification context)
{
var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
identity.AddClaim(ClaimTypes.Name, "me");
identity.AddClaim(ClaimTypes.Email, "me@gmail.com");
var claimsPrincipal = new ClaimsPrincipal(identity);
context.Validated(claimsPrincipal);
return Task.FromResult<object>(null);
}
在资源服务器上,我在其 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;
});
});
在 Fiddler 上,我请求一个令牌,我得到了一个:
POST /token HTTP/1.1
Host: localhost:61854
Content-Type: application/x-www-form-urlencoded
username=admin&password=aaa000&grant_type=password
所以现在我使用该访问令牌从资源服务器访问受保护的资源:
GET /api/values HTTP/1.1
Host: localhost:54408
Content-Type: application/json;charset=utf-8
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI.....
我现在收到此错误 - 受众验证失败。听众:'empty'。不匹配 validationParameters.ValidAudience: 'http://localhost:54408' 或 validationParameters.ValidAudiences: 'null'.
我认为原因是因为我从未在身份验证服务器(在 app.UseOpenIdConnectServer(...))上设置观众,所以我认为它没有将观众信息写入令牌。所以我需要在 auth 服务器上设置一个观众(就像在 IdentityServer3 中所做的那样),但是我在选项对象上找不到 属性 让我这样做。
AspNet.Security.OpenIdConnect.Server 是否要求授权和资源在同一台服务器上?
是否在将 ClaimsPrincipal 放在一起时完成设置受众,如果是,如何设置?
我是否需要编写自定义受众验证程序并将其连接到系统? (我当然希望答案是否定的。)
Does AspNet.Security.OpenIdConnect.Server require the auth and resource to be in the same server?
不,你当然可以把这两个角色分开。
如您所知,如果不明确指定,授权服务器无法确定访问令牌的 destination/audience,而访问令牌是在没有 [=11= 的情况下颁发的] OAuth2 承载中间件默认要求声明。
解决这个问题很简单:只需在创建身份验证票据时调用 ticket.SetResources(resources)
,授权服务器就会确切知道应该在 aud
索赔。
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"
});