验证 AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) 颁发的令牌

Validating Tokens Issued by AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)

我正在使用 Visual Studio 2015 Enterprise 和 ASP.NET vNext Beta8 构建一个端点,该端点同时发布和使用 JWT 令牌。我最初是通过自己生成令牌来解决这个问题的,如 所述。 后来@Pinpoint 的一个有用的 透露 AspNet.Security.OpenIdConnect.Server (a.k.a.OIDC) 可以配置为为我发行和使用令牌。

所以我按照这些说明,建立了一个端点,并通过从 postman 提交 x-www-form-urlencoded post 我收到了一个合法的令牌:

{
  "token_type": "bearer",
  "access_token": "eyJ0eXAiO....",
  "expires_in": "3599"
}

这很棒,但也是我遇到困难的地方。现在,我如何注释控制器操作以便它需要此不记名令牌?

我以为我所要做的就是用 [Authorize("Bearer")], 添加认证方案:

        services.AddAuthorization
        (
            options => 
            {
                options.AddPolicy
                (
                    JwtBearerDefaults.AuthenticationScheme, 
                    builder => 
                    {
                        builder.
                        AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                        RequireAuthenticatedUser().
                        Build();
                    } 
                );
            }
        );

然后使用 "Authorization bearer eyJ0eXAiO...." header 调用我的控制器操作,就像我在之前的示例中所做的那样。可悲的是,所有这些方法似乎都产生了一个异常:

An unhandled exception occurred while processing the request.

SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:50000

WebException: Unable to connect to the remote server

HttpRequestException: An error occurred while sending the request.

IOException: IDX10804: Unable to retrieve document from: 'http://localhost:50000/.well-known/openid-configuration'. Microsoft.IdentityModel.Logging.LogHelper.Throw(String message, Type exceptionType, EventLevel logLevel, Exception innerException)

InvalidOperationException: IDX10803: Unable to obtain configuration from: 'http://localhost:50000/.well-known/openid-configuration'. Inner Exception: 'IDX10804: Unable to retrieve document from: 'http://localhost:50000/.well-known/openid-configuration'.'.


考虑以下步骤来重现(但请不要考虑此生产价值代码):

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthorization
        (
            options => 
            {
                options.AddPolicy
                (
                    JwtBearerDefaults.AuthenticationScheme, 
                    builder => 
                    {
                        builder.
                        AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
                        RequireAuthenticatedUser().
                        Build();
                    } 
                );
            }
        );
        services.AddAuthentication();
        services.AddCaching();
        services.AddMvc();
        services.AddOptions();
    }

    // Configure is called after ConfigureServices is called.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IOptions<AppSettings> appSettings)
    {
        app.UseDeveloperExceptionPage();

        // Add a new middleware validating access tokens issued by the OIDC server.
        app.UseJwtBearerAuthentication(options => {
            options.AutomaticAuthentication = true;
            options.Audience = "http://localhost:50000/";
            options.Authority = "http://localhost:50000/";
            options.ConfigurationManager = new ConfigurationManager<OpenIdConnectConfiguration>
            (
                metadataAddress : options.Authority + ".well-known/openid-configuration",
                configRetriever : new OpenIdConnectConfigurationRetriever(),
                docRetriever    : new HttpDocumentRetriever { RequireHttps = false }
            );
        });

        // Add a new middleware issuing tokens.
        app.UseOpenIdConnectServer
        (
            configuration => 
            {
                configuration.Options.TokenEndpointPath= "/authorization/v1";
                configuration.Options.AllowInsecureHttp = true;
                configuration.Provider = new OpenIdConnectServerProvider {

                    OnValidateClientAuthentication = context => 
                    {
                        context.Skipped();
                        return Task.FromResult<object>(null);
                    },

                    OnGrantResourceOwnerCredentials = context => 
                    {
                        var identity = new ClaimsIdentity(OpenIdConnectDefaults.AuthenticationScheme);
                        identity.AddClaim( new Claim(ClaimTypes.NameIdentifier, "todo")  );
                        identity.AddClaim( new Claim("urn:customclaim", "value", "token id_token"));
                        context.Validated(new ClaimsPrincipal(identity));
                        return Task.FromResult<object>(null);
                    }
                };
            }
        );

        app.UseMvc();
    }
}
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET: api/values
    [Authorize("Bearer")] 
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

如果我在上面尝试的 [Authorize("Bearer")] 方法是错误的方法,如果有人可以帮助我了解如何摄取 JWT 令牌的最佳实践,我将不胜感激OIDC.

谢谢。

options.Authority对应发行人地址(即您的OIDC服务器地址)。

http://localhost:50000/ 似乎不正确,因为您稍后在问题中使用 http://localhost:37734/ 。尝试修复 URL 再试一次。