使用Azure B2C的ASP.NET MVC刷新ID令牌问题

eaf3rand  于 2023-01-14  发布在  .NET
关注(0)|答案(1)|浏览(84)

我正在开发一个使用Azure B2C身份验证的ASP.NET MVC应用,要求在ID令牌过期(IIS会话未过期)后,任何后续操作调用都应使用刷新令牌自动刷新ID令牌,然后继续执行,无需重新登录。
问题:
1.解决方案是否合理?
1.刷新ID令牌并设置Cookie后,如何重定向到原始URL并继续执行而无需重新登录?
谢谢,任何想法都是高度赞赏。
这是我的代码:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    var refreshToken = HttpContext.Current.Request.Cookies["msal.refreshtoken"];

    if (refreshToken != null && !string.IsNullOrEmpty(refreshToken.Value))
    {
        var newIdToken = TokenService.RefreshIdToken(refreshToken.Value);

        var idTokenCookie = new HttpCookie("msal.idtoken", newIdToken)
            {
                Secure = true,
                HttpOnly = true
            };

        HttpContext.Current.Response.Cookies.Set(idTokenCookie);

        return;
    }
}

// TokenService.RefreshIdToken
public static string RefreshIdToken(string refreshToken)
{
    var policyName = ConfigurationManager.AppSettings["ida:SignUpSignInPolicyId"];
    var B2CDomain = ConfigurationManager.AppSettings["ida:B2CDomain"];
    var tenant = ConfigurationManager.AppSettings["ida:Tenant"];
    var clientId = ConfigurationManager.AppSettings["ida:ClientId"];
    var clientSecret = ConfigurationManager.AppSettings["ida:ClientSecret"];
    var tokenEndpointUri = $"https://{B2CDomain}/{tenant}/{policyName}/oauth2/v2.0/token";
    var httpClient = new HttpClient();

    var requestBodyDict = new Dictionary<string, string>
        {
            { "grant_type" , "refresh_token" },
            { "client_id" , clientId },
            { "client_secret" , clientSecret },
            { "scope" , $"openid" },
            { "refresh_token" , refreshToken }
        };

    var request = new HttpRequestMessage
        {
            RequestUri = new Uri(tokenEndpointUri),
            Method = HttpMethod.Post,
            Content = new FormUrlEncodedContent(requestBodyDict)
        };

    var task = Task.Run(() => httpClient.SendAsync(request));
    task.Wait();

    var response = task.Result;

    var task1 = Task.Run(() => response.Content.ReadAsStringAsync());
    task1.Wait();
    var responseString = task1.Result;

    if (response.IsSuccessStatusCode)
    {
        var idToken = (string)JsonConvert.DeserializeObject<dynamic>(responseString).id_token.ToString();
        return idToken;
    }
    else
    {
        throw new Exception();
    }
}
jdgnovmf

jdgnovmf1#

有几个想法太长了,无法在评论中提出:
1.是的,“使用刷新令牌获取新的id令牌”的基本思想是它应该如何工作。
1.谷歌搜索这个问题会发现一系列令人困惑的例子可以模仿:-(例如Microsoft’s Azure Samples on GitHub for A/D auth for a web app(与webapi或SPA相对)
1.解决这类身份认同问题的基本方法是,找一个权威的例子,然后照着做,因为这样可以减少你犯尴尬错误的风险。(例如:Auth0’s example for this scenario要求获取一个新的refresh_token和一个新的id_token。不这样做可能没问题,但当refresh令牌过期时,用户将被迫重新登录。* 然后 * 您将忍不住使用超长-生存期刷新令牌,稍微放松安全性)
1.如果你找不到权威的例子,考虑一下raising an issue or commenting on one
OTOH,如果你写的代码工作,那么也许你已经做到了!
找到一个例子来模仿 * 后 * 你已经开始的问题是试图找到正确的例子,你已经作出了技术选择。它可能更容易开始一个空项目,按照教程,让教程的工作,然后复制到您的应用解决方案。
要将用户发送回其原始目标,您应该能够

var originalUrl= HttpContext.Current.Request.Url;
HttpContext.Current.Response.Redirect(original);

但只有在成功获取id_token的情况下才这样做,否则将创建无限循环。

相关问题