Azure AD单点登录配置后C#/AngularJS应用陷入重定向循环求助
这种Azure AD SSO集成后的重定向循环问题我之前也碰到过,结合你的代码和请求日志,咱们从这几个方向排查:
1. Cookie 安全配置与HTTPS适配问题
从日志里能看到有GET /portal - 80的HTTP请求,随后被302重定向。如果你的应用实际运行在HTTPS(443端口),但Cookie认证的配置没跟上,就会导致浏览器无法在HTTPS请求中携带认证Cookie,服务器每次都判定未登录,触发重定向。
检查你的CookieAuthenticationOptions,建议显式设置:
app.UseCookieAuthentication(new CookieAuthenticationOptions { CookieSecure = CookieSecureOption.Always, // 强制仅在HTTPS下传递Cookie CookieHttpOnly = true, AuthenticationType = CookieAuthenticationDefaults.AuthenticationType });
另外,确保服务器端已经配置了强制HTTPS跳转,避免HTTP请求干扰认证流程。
2. Azure AD应用注册的回调URL不匹配
Azure AD对回调URL的校验非常严格,必须和你应用实际接收授权码的地址完全一致(包括协议、域名、端口、路径,甚至大小写)。
看日志里的请求是POST到/portal,你需要确认Azure AD应用注册中的「回复URL」是否设置为https://你的域名/portal,有没有拼写错误、多了/少了斜杠,或者用了HTTP而不是HTTPS?
3. 授权码兑换时的重定向URI错误
你的代码中用HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)获取回调URI,但如果请求是从HTTP(80端口)过来的,这个方法会返回HTTP地址,而Azure AD期望的是你注册的HTTPS回调地址,这会导致AcquireTokenByAuthorizationCodeAsync调用失败,无法生成有效的认证票据,进而无法设置登录Cookie,触发循环。
建议改成硬编码正确的HTTPS回调地址,比如:
return authContext.AcquireTokenByAuthorizationCodeAsync( code, new Uri("https://yourdomain/portal"), // 替换为实际的HTTPS回调地址 credential, graphResourceId);
4. 令牌缓存实现问题
你用了自定义的ADALTokenCache,如果这个缓存的实现有bug(比如无法正确存储/读取令牌),会导致AcquireTokenByAuthorizationCodeAsync无法完成令牌兑换,认证流程中断,服务器无法识别已登录用户,继续重定向到登录页。
可以先临时替换成默认的缓存(去掉new ADALTokenCache(signedInUserID),直接传null),测试是否还会出现循环:
AuthenticationContext authContext = new AuthenticationContext(Authority, null);
如果问题消失,那就是自定义令牌缓存的问题,需要排查缓存的读写逻辑。
5. 应用权限或密钥配置错误
检查Azure AD应用注册的以下配置:
- 客户端密钥(appKey):确认密钥是否正确、未过期,有没有在代码中写错。
- API权限:是否添加了Microsoft Graph的必要权限(比如
User.Read),并且已经完成管理员同意(如果需要)。
如果密钥错误或权限不足,AcquireTokenByAuthorizationCodeAsync会抛出异常,导致认证失败,触发重定向循环。
调试建议
- 在
AuthorizationCodeReceived事件中添加日志,捕获AcquireTokenByAuthorizationCodeAsync的异常信息,看是否有明确的错误提示。 - 打开浏览器的开发者工具(F12),查看「Application」标签下的Cookie,确认是否生成了
.AspNet.Cookies(或自定义名称)的认证Cookie。 - 用抓包工具(比如Fiddler)跟踪请求流程,看重定向过程中Cookie是否被正确传递,以及Azure AD返回的响应是否有错误信息。
内容的提问来源于stack exchange,提问作者user3376642

