Validating Tokens Issued by AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)(验证 AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) 颁发的令牌)
问题描述
我正在使用 Visual Studio 2015 Enterprise 和 ASP.NET vNext Beta8 来构建一个端点,该端点发出并使用 JWT 令牌.我最初是通过自己生成令牌来解决这个问题的,如 所述这里.后来@Pinpoint 的一篇有用的文章显示,AspNet.Security.OpenIdConnect.Server(又名 OIDC)可以配置为为我发放和使用令牌.
I am using Visual Studio 2015 Enterprise and ASP.NET vNext Beta8 to build an endpoint that both issues and consumes JWT tokens. I Originally approached this by generating the tokens myself, as described here. Later a helpful article by @Pinpoint revealed that AspNet.Security.OpenIdConnect.Server (a.k.a. OIDC) can be configured to issue and consume the tokens for me.
所以我按照这些说明,建立了一个端点,并从 邮递员 我收到了一个合法的令牌:
So I followed those instructions, stood up an endpoint, and by submitting an x-www-form-urlencoded post from postman I receive back a legit token:
{
"token_type": "bearer",
"access_token": "eyJ0eXAiO....",
"expires_in": "3599"
}
这很棒,但也是我卡住的地方.现在,我如何注释控制器操作以使其需要此不记名令牌?
This is great but also where I get stuck. Now, how do I annotate a controller action so that it demands this bearer token?
我以为我要做的就是用[Authorize("Bearer")],添加认证方案:
I thought all I would have to do is decorate my controller method with the [Authorize("Bearer")], add an authentication scheme:
services.AddAuthorization
(
options =>
{
options.AddPolicy
(
JwtBearerDefaults.AuthenticationScheme,
builder =>
{
builder.
AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme).
RequireAuthenticatedUser().
Build();
}
);
}
);
然后像我在前面的示例中所做的那样,使用Authorization Bearer eyJ0eXAiO...."标题调用我的控制器操作.可悲的是,所有这些方法似乎都会产生一个异常:
And then call my controller action with the "Authorization bearer eyJ0eXAiO...." header as I had done in my previous example. Sadly, all this approach seems to do though is generate an exception:
处理请求时发生未处理的异常.
An unhandled exception occurred while processing the request.
SocketException: 无法建立连接,因为目标机器主动拒绝了它 127.0.0.1:50000
SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:50000
WebException: 无法连接到远程服务器
WebException: Unable to connect to the remote server
HttpRequestException: 发送请求时出错.
HttpRequestException: An error occurred while sending the request.
IOException:IDX10804:无法从以下位置检索文档:'http://localhost:50000/.well-known/openid-configuration'.Microsoft.IdentityModel.Logging.LogHelper.Throw(String message, Type exceptionType, EventLevel logLevel, Exception innerException)
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 get configuration from: 'http://localhost:50000/.well-known/openid-configuration'.内部异常:'IDX10804:无法从以下位置检索文档:'http://localhost:50000/.well-known/openid-configuration'.'.
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'.'.
考虑以下步骤来重现(但请不要考虑这个生产有价值的代码):
Consider the following steps to reproduce (but please don't consider this production worthy code):
按照描述应用 ASP.NET Beta8 工具 这里
打开 Visual Studio Enterprise 2015 并创建一个新的 Web API ASP.NET 5 Preview Template 项目
Open Visual Studio Enterprise 2015 and create a new Web API ASP.NET 5 Preview Template project
更改 project.json
Change 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",
节点模块"
],
发布排除":[
".user",
".vspscc"
]
}
{
"webroot": "wwwroot",
"version": "1.0.0-*",
"dependencies": {
"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"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
},
"frameworks": {
"dnx451": { }
},
"exclude": [
"wwwroot",
"node_modules"
],
"publishExclude": [
".user",
".vspscc"
]
}
如下更改 Startup.cs(这是@Pinpoint 的原始文章提供的;我已删除评论并添加了 AddAuthorization snip):
Change Startup.cs as follows (this is courtesy of @Pinpoint's original article; I have removed comments and added the AddAuthorization snip):
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,其中grant_type"为password",username"为任何内容,password"为任何内容,resource"为 API 端点的地址.例如,我的特定 URL 是 http://localhost:37734/authorization/v1.
Run the project, and acquire a token using postman. To acquire a token use x-www-form-urlencoded POST with "grant_type" of "password", "username" anything, "password" anything and "resource" the address of the API endpoint. My particular URL for example is http://localhost:37734/authorization/v1.
复制 Base64 编码的令牌,然后使用令牌通过 邮递员.要使用令牌,请使用标头 Content-Type application/json 和 Authorization Bearer eyJ0eXAiO....(您的令牌)进行 GET.我的特定 URL 是 http://localhost:37734/api/values.
Copy the Base64 encoded token, then use the token to call the wizarded values controller using postman. To use the token make a GET with the headers Content-Type application/json and Authorization bearer eyJ0eXAiO....(your token). My particular URL is http://localhost:37734/api/values.
注意前面提到的异常.
如果我在上面尝试的 [Authorize("Bearer")] 方法是错误的方法,如果有人能帮助我了解如何使用 OIDC 摄取 JWT 令牌的最佳实践,我将非常感激.
If the [Authorize("Bearer")] approach I'm trying above is the wrong way to go I would be very appreciative if someone could help me understand best practices for how to ingest the JWT token using OIDC.
谢谢.
推荐答案
options.Authority对应issuer地址(即你的OIDC服务器地址).options.Authoritycorresponds to the issuer address (i.e the address of your OIDC server).http://localhost:50000/似乎不正确,因为您稍后在问题中使用http://localhost:37734/.尝试修复 URL,然后再试一次.http://localhost:50000/doesn't seem to be correct as you're usinghttp://localhost:37734/later in your question. Try fixing the URL and give it another try.这篇关于验证 AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) 颁发的令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:验证 AspNet.Security.OpenIdConnect.Server (ASP.NET vNext) 颁
基础教程推荐
- JSON.NET 中基于属性的类型解析 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 全局 ASAX - 获取服务器名称 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
