You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI WebAuthenticator集成Microsoft SSO时未返回IdToken且AccessToken非JWT格式的问题

MAUI WebAuthenticator集成Microsoft SSO时未返回IdToken且AccessToken非JWT格式的问题

我仔细看了你的代码和配置细节,这两个问题其实都和Microsoft Account认证的端点版本配置有关,咱们一步步来解决:

问题根源分析

默认情况下,ASP.NET Core的AddMicrosoftAccount使用的是微软身份认证的v1端点,这个端点返回的Access Token是不透明的(非JWT格式),并且对OpenID Connect的支持不完整,所以即使你添加了openid Scope,也不会返回IdToken。而你在Azure中配置的应用是v2版本(Access Token版本为2),必须强制使用v2端点才能获取到JWT格式的Access Token和IdToken。


解决方案步骤

1. 强制Microsoft Account使用v2认证端点

修改你ASP.NET Web App的认证配置,在AddMicrosoftAccount中添加Authority配置,指定使用v2端点:

builder.Services.AddAuthentication(options => {
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddMicrosoftAccount(options => {
    options.ClientId = "ClientId";
    options.ClientSecret = "ClientSecret";
    options.SaveTokens = true;
    options.CallbackPath = "/mobileauth";
    // 关键:强制使用v2端点,才能返回JWT Token和IdToken
    options.Authority = "https://login.microsoftonline.com/common/v2.0";
    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    options.Scope.Add("offline_access");
    options.Scope.Add("https://graph.microsoft.com/User.Read");
    // 可选:明确指定ResponseType,确保请求IdToken
    options.ResponseType = "code id_token";
});

2. 在AuthController中获取并传递IdToken

修改你的AuthController,添加获取IdToken的逻辑,并将其传递给MAUI端:

[Route("mobileauth")]
[ApiController]
public class AuthController : ControllerBase {
    const String CallbackScheme = "myapp";

    [HttpGet("{scheme}")]
    public async Task Get([FromRoute] String scheme) {
        var auth = await Request.HttpContext.AuthenticateAsync(scheme);
        
        // 简化认证成功判断逻辑
        if (!auth.Succeeded) {
            await Request.HttpContext.ChallengeAsync(scheme);
            return; // 必须return,避免后续代码执行
        }

        var claims = auth.Principal?.Claims ?? throw new InvalidOperationException("Claims are required");
        var email = claims?.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Email)?.Value;
        
        // 获取IdToken和JWT格式的AccessToken
        var accessToken = auth.Properties.GetTokenValue("access_token");
        var idToken = auth.Properties.GetTokenValue("id_token");
        var refreshToken = auth.Properties.GetTokenValue("refresh_token");

        var queryParams = new Dictionary<String, String> {
            { "access_token", accessToken ?? throw new InvalidOperationException("Access token is required") },
            { "id_token", idToken ?? throw new InvalidOperationException("Id token is required") },
            { "refresh_token", refreshToken ?? String.Empty },
            { "expires_in", (auth.Properties.ExpiresUtc?.ToUnixTimeSeconds() ?? -1).ToString() },
            { "email", email ?? throw new InvalidOperationException("Email is required") }
        }
        .Where(kvp => !String.IsNullOrEmpty(kvp.Value) && kvp.Value != "-1")
        .Select(kvp => $"{WebUtility.UrlEncode(kvp.Key)}={WebUtility.UrlEncode(kvp.Value)}");

        var query = String.Join("&", queryParams);
        var url = $"{CallbackScheme}://#{query}";
        Request.HttpContext.Response.Redirect(url);
    }
}

3. MAUI端解码JWT Token创建ClaimsIdentity

现在MAUI端拿到的Access Token和IdToken都是JWT格式了,你可以用System.IdentityModel.Tokens.Jwt库解码并创建身份信息:

using System.IdentityModel.Tokens.Jwt;

var authResult = await WebAuthenticator.Default.AuthenticateAsync(
    new Uri("https://10.0.2.2:7016/mobileauth/Microsoft"),
    new Uri("myapp://"));

// 解码IdToken获取用户身份信息
var idToken = authResult.Properties["id_token"];
var jwtHandler = new JwtSecurityTokenHandler();
var jwtToken = jwtHandler.ReadJwtToken(idToken);

// 创建ClaimsIdentity供MAUI应用使用
var userIdentity = new ClaimsIdentity(jwtToken.Claims, "MicrosoftAuth");
var userPrincipal = new ClaimsPrincipal(userIdentity);
// 后续可以将Principal存入应用的身份验证上下文

额外验证点

  • 确认Azure应用注册的重定向URI已添加你的Web App的https://<你的域名>/mobileauth地址
  • 确保你的Azure应用是v2版本的应用注册(对应你提到的Access Token版本2)
  • 测试时可以用JWT解析工具(比如jwt.io)验证返回的Token是否为JWT格式

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:33:03