問題描述
我正在使用 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.Authority
corresponds 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) 頒發的令牌的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!