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

时间:2015-10-28 21:30:36

标签: asp.net jwt openid-connect aspnet-contrib

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

所以我按照这些说明,站了一个端点,然后从postman提交了一个x-www-form-urlencoded帖子,我收到了一个合法的令牌:

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

这很棒但也让我陷入困境。现在,如何注释控制器操作以便它需要此持有者令牌?

我认为我所要做的就是用。装饰我的控制器方法 [授权(" Bearer")],添加认证方案:

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

然后使用"授权承载eyJ0eXAiO调用我的控制器操作...."我在上一个例子中所做的标题。可悲的是,所有这些方法似乎都会产生例外:

  

处理请求时发生未处理的异常。

     

SocketException:无法建立连接,因为目标计算机主动拒绝它127.0.0.1:50000

     

WebException:无法连接到远程服务器

     

HttpRequestException:发送请求时发生错误。

     

IOException:IDX10804:无法从:' http://localhost:50000/.well-known/openid-configuration'中检索文档。   Microsoft.IdentityModel.Logging.LogHelper.Throw(String message,Type exceptionType,EventLevel logLevel,Exception innerException)

     

InvalidOperationException:IDX10803:无法从:' http://localhost:50000/.well-known/openid-configuration'获取配置。内部异常:' IDX10804:无法从以下位置检索文档:' http://localhost:50000/.well-known/openid-configuration'。'。


请考虑以下步骤来重现(但请不要考虑这个有价值的代码):

  • 按照here

  • 所述应用ASP.NET Beta8工具
  • 打开Visual Studio Enterprise 2015并创建新的Web API ASP.NET 5预览模板项目

  • 更改project.json

    {
      " webroot":" wwwroot",
      "版本":" 1.0.0 - *",

      "依赖":{
        " Microsoft.AspNet.IISPlatformHandler":" 1.0.0-beta8",
        " Microsoft.AspNet.Mvc":" 6.0.0-beta8",
        " Microsoft.AspNet.Server.Kestrel":" 1.0.0-beta8",
        " Microsoft.AspNet.Authentication.JwtBearer":" 1.0.0-beta8",
        " AspNet.Security.OpenIdConnect.Server":" 1.0.0-beta3",
        " Microsoft.AspNet.Authentication.OpenIdConnect":" 1.0.0-beta8",
        " Microsoft.Framework.ConfigurationModel.Json":" 1.0.0-beta4",
        " Microsoft.AspNet.Diagnostics":" 1.0.0-beta8"
      },

      "命令":{
        " web":" Microsoft.AspNet.Server.Kestrel"
      },

      "框架":{
        " dnx451":{}
      },

      "排除":[
        " wwwroot的&#34 ;,
        " node_modules"
      ],
      " publishExclude":[
        "的的.user&#34 ;,
        "
    .vspscc"
      ]
    }

  • 按如下方式更改Startup.cs(这是@Pinpoint的原创文章;我删除了评论并添加了AddAuthorization剪辑):

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();
    }
}
  • 更改wizarded ValuesController.cs以指定Authorize属性:
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET: api/values
    [Authorize("Bearer")] 
    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}
  • 运行项目,并使用postman获取令牌。要获取令牌,请使用x-www-form-urlencoded POST&#34; grant_type&#34; &#34;密码&#34;,&#34;用户名&#34;什么,&#34;密码&#34;什么和&#34;资源&#34; API端点的地址。我的特定网址是http://localhost:37734/authorization/v1

  • 复制Base64编码的令牌,然后使用令牌使用postman调用wizarded值控制器。要使用令牌,请使用标题Content-Type application / json和Authorization bearer eyJ0eXAiO ....(您的令牌)进行GET。我的特定网址是http://localhost:37734/api/values

  • 观察前面提到的例外情况。

如果[授权(&#34; Bearer&#34;)]方法我尝试上面的方法是错误的,我会非常感激,如果有人能帮助我理解如何摄取的最佳实践使用OIDC的JWT令牌。

谢谢。

1 个答案:

答案 0 :(得分:3)

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

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