在重定向 URL 中使用 id_token 作为参数的重定向用户会导致标识用户为 Null



我一直在使用 AADB2C 身份验证,并为将用户重定向到主页而苦苦挣扎,id_token作为重定向 URL 中的片段。 以下是我如何在帐户控制器中启动身份验证质询

public class AccountController : Controller
{
public AzureAdB2COptions AzureAdB2COptions { get; set; }
public AccountController(IOptions<AzureAdB2COptions> b2cOptions)
{
AzureAdB2COptions = b2cOptions.Value;
}
// GET: /<controller>/
[HttpGet]
public IActionResult SignUpSignIn()
{
var redirectUrl = "http://localhost:7878/dasdfsd/home";
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectDefaults.AuthenticationScheme);
}
}

下面是我将用户重定向到重定向 URL(http://localhost:7878/dgddfg/home) 的地方,ID 令牌与 URL 一起分段

public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context)
{
// Use MSAL to swap the code for an access token
// Extract the code from the response notification
var code = context.ProtocolMessage.Code;
string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
try
{
AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' '));
context.HandleCodeRedemption(result.AccessToken, result.IdToken);
context.HandleResponse();
context.Response.Redirect("dfgfd/home#grant_type=" + context.ProtocolMessage.GrantType + "&id_token=" + result.IdToken);
}
catch (Exception)
{
//TODO: Handle
throw;
}
}

当用户使用 JavaScript 重定向到主页时,我从 URL 获取id_token并调用帐户控制器操作("GetAccessTokenAsync")以使用身份用户获取访问令牌

[HttpGet]
public async Task<string> GetAccessTokenAsync()
{
string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
TokenCache userTokenCache = new MSALSessionCache(signedInUserID , HttpContext).GetMsalCacheInstance();
ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);
try
{
var userAccounts = await cca.GetAccountsAsync();
if (userAccounts == null && userAccounts.Count()==0)
{
throw new Exception("The User is NULL.  Please clear your cookies and try again.  Specifically delete cookies for 'login.microsoftonline.com'.  See this GitHub issue for more details: https://github.com/Azure-Samples/active-directory-b2c-dotnet-webapp-and-webapi/issues/9");
}
AuthenticationResult result = await cca.AcquireTokenSilentAsync(AzureAdB2COptions.ApiScopes.Split(' '),userAccounts.FirstOrDefault());
return result.AccessToken;
}
catch (Exception ex)
{
//TODO: Handle
return "";
}
}

这里的问题是操作方法中的HttpContext.User为空。 但是,如果我删除我编写重定向URL的部分,并在OnAuthorizationCodeReceived中附加id_token并context.HandleResponse();, 当执行的 getAccessToken 操作HttpContext.User不会为空时,用户将在没有 ID 令牌的情况下被重定向,用户将拥有包括声明在内的所有详细信息。

如何在 url 中使用 id 令牌重定向用户,以及如何在不为 null 的情况下让用户在控制器方法中获取访问令牌?这和饼干有关吗?

我不知道为什么在javascript中需要ID令牌,ID令牌包含用户配置文件信息(如用户名,电子邮件等),这些声明是关于用户的陈述,但不应包含敏感信息。

如果要获取用户声明,可以从对象查询声明HttpContext.User并将相关声明传递给客户端。 或者使用图形 API 直接从 Azure AD 获取用户的配置文件信息Microsoft。

您可以使用 cookie 将 id 令牌存储在OnAuthorizationCodeReceived事件中,例如:

context.Response.Cookies.Append("IDToken", context.ProtocolMessage.IdToken, new CookieOptions()
{
Path = "/",
HttpOnly = false,
Secure = true
});

并通过以下方式访问服务器端的值:

var idToken= Request.Cookies["IDToken"];

但是你应该关注 安全问题 .当与 HttpOnly cookie 标志(=true) 一起使用时,无法通过 JavaScript 访问,并且不受 XSS 的影响。您还可以设置安全 cookie 标志,以确保 cookie 仅通过 HTTPS 发送。但是,Cookie 容易受到跨站点请求伪造 (CSRF) 攻击。您可以参考此线程,其中提供了有关该主题的详细讨论。

简而言之,您可以将ID令牌存储在cookie中。但我建议从HttpContext.User对象中获取用户声明。

相关内容

最新更新