分离验证和资源服务器与AspNet.Security.OpenIdConnect - 观众? [英] Separating Auth and Resource Servers with AspNet.Security.OpenIdConnect - the Audience?

查看:992
本文介绍了分离验证和资源服务器与AspNet.Security.OpenIdConnect - 观众?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个例子<一个href=\"https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/vNext/samples/Mvc/Mvc.Server/Startup.cs\"相对=nofollow> AspNet.Security.OpenIdConnect.Server 看起来对我来说既是一种权威性和资源服务器。我想分开的。我已经这样做了。

在auth服务器的Startup.Config,我有以下设置:

  app.UseOpenIdConnectServer(选项=&GT; {                options.AllowInsecureHttp = TRUE;
                options.ApplicationCanDisplayErrors = TRUE;
                options.AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme;
                options.Issuer =新的System.Uri(HTTP://本地主机:61854); //这个auth服务器
                options.Provider =新AuthorizationProvider();
                options.TokenEndpointPath =新PathString(/标记);
                options.UseCertificate(新X509Certificate2(env.ApplicationBasePath +\\\\ mycertificate.pfx​​,mycertificate));            });

我有一个AuthorizationProvider写的,但我不认为这是有关我的本期(但可能有用)。在其GrantResourceOwnerCredentials覆盖,我硬code索赔主体,使其验证每一个令牌请求:

 公众覆盖任务GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsNotification上下文)
        {
            VAR身份=新ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);            identity.AddClaim(ClaimTypes.Name,我);
            identity.AddClaim(ClaimTypes.Emailme@gmail.com);
            VAR claimsPrincipal =新ClaimsPrincipal(身份);            context.Validated(claimsPrincipal);
            返回Task.FromResult&LT;对象&gt;(NULL);
        }

在资源服务器,我在其Startup.config以下内容:

  app.UseWhen(上下文=&GT; context.Request.Path.StartsWithSegments(新PathString(/ API)),分支= GT;
         {
             branch.UseOAuthBearerAuthentication(选项=&GT; {
                 options.Audience =HTTP://本地主机:54408; //这个资源服务器,我相信。
                 options.Authority =HTTP://本地主机:61854; //该认证服务器
                 options.AutomaticAuthentication = TRUE;
             });
         });

在提琴手,我问了一个道理,我得到一个:

  POST /令牌HTTP / 1.1
主机:本地主机:61854
内容类型:应用程序/ x-WWW的形式urlen codeD用户名=管理员和放大器;密码= aaa000&安培; grant_type =密码

所以,现在我使用的访问令牌从资源服务器访问受保护资源:

  GET / API /值HTTP / 1.1
主机:本地主机:54408
内容类型:应用程序/ JSON的;字符集= UTF-8
授权:承载eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI .....

我现在得到这个错误 - 观众验证失败。听众:'空'。没有匹配validationParameters.ValidAudience:的http://本地主机:54408 或validationParameters.ValidAudiences:'空'

我想原因是因为我从来没有设定在auth服务器的观众(在app.UseOpenIdConnectServer(...)),所以我不认为它写了观众的信息令牌。所以,我需要设置在auth服务器的观众(如什么是IdentityServer3完成),但在选择对象,将让我做,我找不到一个属性。

是否AspNet.Security.OpenIdConnect.Server需要权威性和资源是在同一台服务器?

时设置ClaimsPrincipal放在一起时所做的观众,如果是这样,怎么样?

请问我需要写一个自定义的验证对象,并把它挂到系统? (我当然希望这个问题的答案是否定的。)


解决方案

  

是否AspNet.Security.OpenIdConnect.Server需要权威性和资源是在同一台服务器?


没有,你当然可以分开两个角色。

正如你已经想通了,如果你没有明确指定,授权服务器有没有办法确定一个访问令牌,该令牌没有澳元<发行的目的地/全场/ code>由承载的OAuth2中间件,默认需要索赔。

解决这个问题很简单:只需拨打 ticket.SetResources(资源)创建身份验证票证和授权服务器将知道哪些值(S)时(即资源服务器/ API)应该添加澳元索赔(收费)

  app.UseOpenIdConnectServer(选项=&GT; {
    //强制的OpenID Connect服务器中间件使用JWT令牌
    //而不是默认的不透明/加密令牌默认情况下使用的格式。
    options.UseJwtTokens();
});公众覆盖任务GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext上下文){
    VAR身份=新ClaimsIdentity(context.Options.AuthenticationScheme);
    identity.AddClaim(ClaimTypes.NameIdentifier,唯一标识符);    VAR票=新AuthenticationTicket(
        新ClaimsPrincipal(身份),
        新AuthenticationProperties(),
        context.Options.AuthenticationScheme);    //调用SetResources与资源服务器列表
    //访问令牌应该发出。
    ticket.SetResources(resource_server_1);    //调用SetScopes与要授予的范围列表。
    ticket.SetScopes(配置文件,offline_access);    context.Validate(票);    返回Task.FromResult(0);
}app.UseJwtBearerAuthentication(新JwtBearerOptions {
    AutomaticAuthenticate = TRUE,
    AutomaticChallenge = TRUE,
    观众=resource_server_1
    管理局=HTTP://本地主机: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, "me@gmail.com");
            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.1
Host: localhost:61854
Content-Type: application/x-www-form-urlencoded

username=admin&password=aaa000&grant_type=password

So now I use that access token to access a protected resource from the resource server:

GET /api/values HTTP/1.1
Host: localhost:54408
Content-Type: application/json;charset=utf-8
Authorization: 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.UseJwtTokens();
});

public override Task GrantResourceOwnerCredentials(GrantResourceOwnerCredentialsContext context) {
    var identity = new ClaimsIdentity(context.Options.AuthenticationScheme);
    identity.AddClaim(ClaimTypes.NameIdentifier, "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 - 观众?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆