使用AspNet.Security.OpenIdConnect分离Auth和资源服务器 - 受众?

时间:2015-09-26 14:28:26

标签: asp.net-web-api oauth asp.net-core openid-connect aspnet-contrib

AspNet.Security.OpenIdConnect.Server上的示例看起来像auth和资源服务器。我想把它们分开。我已经这样做了。

在auth服务器的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.....

我现在收到此错误 - 受众验证失败。观众:'空'。与validationParameters.ValidAudience不匹配:'http://localhost:54408'或validationParameters.ValidAudiences:'null'。

我认为原因是因为我从未在auth服务器上设置受众(在app.UseOpenIdConnectServer(...)),因此我认为它不会将受众信息写入令牌。所以我需要在auth服务器上设置一个受众(就像在IdentityServer3中所做的那样),但我找不到可以让我这样做的选项对象的属性。

AspNet.Security.OpenIdConnect.Server是否要求auth和资源位于同一服务器中?

在整合ClaimsPrincipal时是否设置了观众,如果是,那该怎么办?

我是否需要编写自定义Audience验证程序并将其连接到系统? (我当然希望答案是否定的。)

1 个答案:

答案 0 :(得分:5)

  

AspNet.Security.OpenIdConnect.Server是否要求auth和资源位于同一服务器中?

不,你当然可以将这两个角色分开。

正如您已经想到的那样,如果您没有明确指定它,授权服务器无法确定访问令牌的目标/受众,该令牌在没有{{1}的情况下发布默认情况下,OAuth2承载中间件需要声明。

解决此问题很简单:只需在创建身份验证票证时调用aud,授权服务器就会准确知道应在ticket.SetResources(resources)中添加哪些值(即资源服务器/ API)如权利要求(一个或多个)。

aud