【发布时间】:2019-08-12 09:18:01
【问题描述】:
在使用code authorization flow 的演示“客户端”网站设置中,当我的用户从我自己的本地身份提供商 (IdentityServer4) 成功登录时,我会收到一个声明我的用户身份的 JWT。这被存储为一个看起来像这样的cookie(用...缩短):
ai_user=kFgLY|2018-12-11T15:40:11.940Z; AMCV_700CFDC5570CBFE67F000101%40AdobeOrg=2121618341%7CMCIDTS%7...ywuxL1PHcA
客户端站点配置如下:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = "cookie";
options.DefaultSignInScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("cookie")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5005";
options.RequireHttpsMetadata = false;
options.RemoteAuthenticationTimeout = TimeSpan.FromMinutes(15);
options.ClientId = "test_pkce_client";
options.ClientSecret = "secret";
options.ResponseType = "code";
options.ResponseMode = "form_post";
options.CallbackPath = "/signin-test";
options.GetClaimsFromUserInfoEndpoint = true;
options.Events.OnRedirectToIdentityProvider = context => HandleRedirectToIDP(context);
options.Events.OnAuthorizationCodeReceived = context => HandleCodeReceived(context);
});
当用户进行身份验证时,我想捕获该 JWT。当我向下游 Web 服务发出请求时,我想传递该 JWT,以便它们可以(独立地)验证用户的身份验证,并且还可以独立地查询该用户是否应该有权执行给定的 API 操作。如果有必要,我还希望我的 Web 服务接受 client credentials grant 进行机器对机器身份验证。
使用 identityserver4 和 .NET Core,我怎样才能做到这一点?如何使我的 Web 服务中的 [Authorize] 注释区分两个流并优雅地处理它?在我的演示 Web 服务中,我的客户端凭据授权工作正常:
.AddIdentityServerAuthentication("token", options =>
{
options.Authority = "https://localhost:5005";
options.RequireHttpsMetadata = false;
options.ApiName = "SomeAPI";
options.ApiSecret = "secret";
});
1) 在我的服务中,如何添加从客户端读取 JWT 的第二种身份验证方法?是不是和启动中的AddJwtBearer()一样简单? 2) 在我的“客户端”中,我如何捕获并发送(以保留)我的授权用户的 JWT 到其他服务?
我认为这行不通,只是为了显示我的意思,从我的“客户”网站中的 [Authorize]'d 控制器中我尝试在我的客户端上尝试的努力
[Authorize]
public IActionResult SecurePage()
{
var client = new System.Net.Http.HttpClient();
client.BaseAddress = new System.Uri("https://localhost:3721/");
client.DefaultRequestHeaders.Add("Cookie", Request.Headers["Cookie"].First());
var apiTask = client.GetAsync("Test");
apiTask.Wait();
string response = apiTask.Result.Content.ReadAsStringAsync().Result;
这显然是 401 来自我的服务。
更新
在得到 d_f 的帮助后,我把我上面的拙劣想法翻译成这样:
[Authorize]
public async Task<IActionResult> SecurePage()
{
string accessToken = await HttpContext.GetTokenAsync("cookie", "access_token");
string idToken = await HttpContext.GetTokenAsync("cookie", "id_token");
var client = new System.Net.Http.HttpClient();
client.BaseAddress = new System.Uri("https://localhost:3721/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var apiTask = client.GetAsync("Test");
apiTask.Wait();
string response = apiTask.Result.Content.ReadAsStringAsync().Result;
诀窍是将用户的 accessToken 视为客户端凭据授予令牌。另外,确保您的客户端启动中的 AddOpenIdConnect 是 options.SaveTokens = true; 并且您的 ResponseType 是 options.ResponseType = "code id_token"; 这将允许 API .AddIdentityServerAuthentication("token", options => 可以读取您的请求并针对 IDP 进行身份验证。
【问题讨论】:
标签: c# asp.net-core oauth identityserver4 openid-connect