在手动隐式流程登录时获取身份令牌 (IdentityServer4)
Get Identity Token on Manual Implicit flow login (IdentityServer4)
我已经设置了身份服务器 4。我已经按照手册示例设置了客户端 here.这是代码。
public async Task<IActionResult> Contact()
{
if (User.Identity.IsAuthenticated) return View();
return await StartAuthentication();
}
private async Task<IActionResult> StartAuthentication()
{
// read discovery document to find authorize endpoint
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
var authorizeUrl = new RequestUrl(disco.AuthorizeEndpoint).CreateAuthorizeUrl(
clientId: "mvc",
responseType: "id_token",
scope: "openid profile",
redirectUri: "http://localhost:5002/home/callback",
state: "random_state",
nonce: "random_nonce",
responseMode: "form_post");
return Redirect(authorizeUrl);
}
public async Task<IActionResult> Callback()
{
var state = Request.Form["state"].FirstOrDefault();
var idToken = Request.Form["id_token"].FirstOrDefault();
var error = Request.Form["error"].FirstOrDefault();
if (!string.IsNullOrEmpty(error)) throw new Exception(error);
if (!string.Equals(state, "random_state")) throw new Exception("invalid state");
var user = await ValidateIdentityToken(idToken);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
return Redirect("/home/contact");
}
public async Task<IActionResult> Logout()
{
//await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
//return Redirect(disco.EndSessionEndpoint);
var idToken = (await HttpContext.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "id_token"));
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
var endSessionUrl = new RequestUrl(disco.EndSessionEndpoint).CreateEndSessionUrl(
postLogoutRedirectUri: "http://localhost:5002/signout-callback-oidc",
idTokenHint: idToken
);
return Redirect(endSessionUrl);
}
目前
var idToken = (await HttpContext.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "id_token"));
为空。
如果我把代码改成
[Authorize]
public async Task<IActionResult> Contact()
{
if (User.Identity.IsAuthenticated) return View();
return await StartAuthentication();
}
基本跳过手动方式,根据启动时的配置自动跳转。 则值为 NOT NULL
我也试过:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, new AuthenticationProperties(new Dictionary<string, string>()
{
[OpenIdConnectParameterNames.IdToken] = idToken
}));
运气不好。
启动代码如下所示:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
});
如上所示手动触发签名时如何设置和获取身份令牌?
我添加了这段代码
var authenticationProperties = new AuthenticationProperties();
var tokens = new List<AuthenticationToken>();
tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = idToken });
authenticationProperties.StoreTokens(tokens);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, authenticationProperties);
阅读 asp.net 安全代码后,我发现 here
看来成功了。
隐式流 returns 标记作为片段,而不是查询参数。如果 OP 支持表单 Post 响应模式,您可以在请求参数中包含 response_mode=form_post 以强制 OP 将 return 令牌作为表单 post 参数,http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html.
我已经设置了身份服务器 4。我已经按照手册示例设置了客户端 here.这是代码。
public async Task<IActionResult> Contact()
{
if (User.Identity.IsAuthenticated) return View();
return await StartAuthentication();
}
private async Task<IActionResult> StartAuthentication()
{
// read discovery document to find authorize endpoint
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
var authorizeUrl = new RequestUrl(disco.AuthorizeEndpoint).CreateAuthorizeUrl(
clientId: "mvc",
responseType: "id_token",
scope: "openid profile",
redirectUri: "http://localhost:5002/home/callback",
state: "random_state",
nonce: "random_nonce",
responseMode: "form_post");
return Redirect(authorizeUrl);
}
public async Task<IActionResult> Callback()
{
var state = Request.Form["state"].FirstOrDefault();
var idToken = Request.Form["id_token"].FirstOrDefault();
var error = Request.Form["error"].FirstOrDefault();
if (!string.IsNullOrEmpty(error)) throw new Exception(error);
if (!string.Equals(state, "random_state")) throw new Exception("invalid state");
var user = await ValidateIdentityToken(idToken);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user);
return Redirect("/home/contact");
}
public async Task<IActionResult> Logout()
{
//await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
//return Redirect(disco.EndSessionEndpoint);
var idToken = (await HttpContext.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "id_token"));
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var disco = await DiscoveryClient.GetAsync("http://localhost:5000");
var endSessionUrl = new RequestUrl(disco.EndSessionEndpoint).CreateEndSessionUrl(
postLogoutRedirectUri: "http://localhost:5002/signout-callback-oidc",
idTokenHint: idToken
);
return Redirect(endSessionUrl);
}
目前
var idToken = (await HttpContext.GetTokenAsync(CookieAuthenticationDefaults.AuthenticationScheme, "id_token"));
为空。
如果我把代码改成
[Authorize]
public async Task<IActionResult> Contact()
{
if (User.Identity.IsAuthenticated) return View();
return await StartAuthentication();
}
基本跳过手动方式,根据启动时的配置自动跳转。 则值为 NOT NULL
我也试过:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, new AuthenticationProperties(new Dictionary<string, string>()
{
[OpenIdConnectParameterNames.IdToken] = idToken
}));
运气不好。
启动代码如下所示:
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = "Cookies";
options.Authority = "http://localhost:5000";
options.RequireHttpsMetadata = false;
options.ClientId = "mvc";
options.SaveTokens = true;
});
如上所示手动触发签名时如何设置和获取身份令牌?
我添加了这段代码
var authenticationProperties = new AuthenticationProperties();
var tokens = new List<AuthenticationToken>();
tokens.Add(new AuthenticationToken { Name = OpenIdConnectParameterNames.IdToken, Value = idToken });
authenticationProperties.StoreTokens(tokens);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, user, authenticationProperties);
阅读 asp.net 安全代码后,我发现 here
看来成功了。
隐式流 returns 标记作为片段,而不是查询参数。如果 OP 支持表单 Post 响应模式,您可以在请求参数中包含 response_mode=form_post 以强制 OP 将 return 令牌作为表单 post 参数,http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html.