先发帖所以要温柔! :)
我正在为Office 365开发一个MVC .NET 5 Web应用程序,并且正在使用OpenIDConnect框架 . 我已经设置了OWIN(3)和ADAL(2)以及我的Azure AD应用程序 . 没有用户操作登录,家庭控制器附加了[Authorize]属性,强制立即登录重定向到Azure AD . 我没有在任何Authorize属性中使用角色 .
The Problem :我可以成功登录我的应用程序 - 一次!首次登录后,我关闭浏览器(或在另一台机器上打开一个新浏览器),然后再次点击该应用程序 . 它将我重定向到我登录的Azure AD登录屏幕,然后它不断在应用程序和Azure之间重定向,直到我得到臭名昭着的400个 Headers 为长期问题 . 查看cookie存储,我发现它是's full of nonces. I check the cache (Vittorio'的EFADALCache配方,虽然我在发现此问题时使用了TokenCache.DefaultShared)并且它有数百行缓存数据(只有一行成功登录生成) .
我可以看到,当重定向通过输出窗口发生时,每次往返都会生成一个新的访问和刷新令牌:
Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - AcquireTokenByAuthorizationCodeHandler: Resource value in the token response was used for storing tokens in the cache
iisexpress.exe Information: 0 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - AcquireTokenByAuthorizationCodeHandler: Resource value in the token response was used for storing tokens in the cache
Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 : 31/07/2015 12:31:52: - TokenCache: Deserialized 1 items to token cache.
iisexpress.exe Information: 0 : 31/07/2015 12:31:52: - TokenCache: Deserialized 1 items to token cache.
Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - TokenCache: Storing token in the cache...
iisexpress.exe Information: 0 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - TokenCache: Storing token in the cache...
Microsoft.IdentityModel.Clients.ActiveDirectory Verbose: 1 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - TokenCache: An item was stored in the cache
iisexpress.exe Information: 0 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - TokenCache: An item was stored in the cache
Microsoft.IdentityModel.Clients.ActiveDirectory Information: 2 : 31/07/2015 12:31:52: 15ad306e-e26d-4827-98dc-dea75853788a - AcquireTokenHandlerBase: === Token Acquisition finished successfully. An access token was retuned:
Access Token Hash: PN5HoBHPlhhHIf1lxZhEWb4B4Hli69UKgcle0w7ssvo=
Refresh Token Hash: 3xmypXCO6MIMS9qUV+37uPD4kPip9WDH6Ex29GdWL88=
Expiration Time: 31/07/2015 13:31:51 +00:00
User Hash: GAWUtY8c4EKcJnsHrO6NOzwcQDMW64z5BNOvVIl1vAI=
当问题发生时,我的OpenIdConnectAuthenticationOptions中的AuthorizationCodeReceived通知正在被点击,所以我知道Azure认为登录成功(否则不会重定向到应用程序):
private static void PrepO365Auth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
//Configure OpenIDConnect, register callbacks for OpenIDConnect Notifications
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = ConfigHelper.ClientId,
Authority = authority,
PostLogoutRedirectUri = "https://localhost:44300/Account/SignedOut",
RedirectUri = "https://localhost:44300/",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = (context) =>
{
ClientCredential credential = new ClientCredential(ConfigHelper.ClientId, ConfigHelper.AppKey);
string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
AuthenticationContext authContext = new AuthenticationContext(authority, new EFADALTokenCache(signedInUserID)); // TokenCache.DefaultShared Probably need a persistent token cache to handle app restarts etc
AuthenticationResult result = authContext.AcquireTokenByAuthorizationCode(
context.Code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, ConfigHelper.GraphResourceId);
return Task.FromResult(0);
},
AuthenticationFailed = context =>
{
context.HandleResponse();
context.Response.Redirect("/Error/ShowError?signIn=true&errorMessage=" + context.Exception.Message);
return Task.FromResult(0);
}
}
});
}
}
我已经使用我自己的Auth属性替换了(在发现问题之后)Authorized属性,继承自AuthorizeAttribute,这样我就可以尝试进入Authorize代码并查看_1226949的源代码,但所有发生的事情都是它跳回来进入我自己的代码:(话虽这么说,我已经覆盖了我能做到的事情,发现 filterContext.HttpContext.User.Identity.IsAuthenticated 是假的,这是有道理的,因为这会导致重定向回到Azure登录 .
所以,我知道:
-
Azure正在接受我的登录并返回相关的令牌
-
在第二次登录时,在OnAuthorization之前,filterContext.HttpContext.User.Identity.IsAuthenticated返回false
-
我的Azure应用程序配置没问题,或根本不进行身份验证
我觉得:
-
MVC Identity设置中有一些错误 . Azure工作正常或根本不进行身份验证 .
-
如果您在另一台计算机上执行第二次登录,则问题就出现了,这不是cookie问题
对不起,这有点长篇大论,但有很多这些无限重定向问题,我需要解释为什么我的情况不同!
我正在寻找的(如果不是答案!)是一个正确的方向,我可以进一步调试 .
感谢您提供的任何帮助!
安迪
5 回答
找到了感兴趣的人的答案 . 这是Katana中的一个已知错误,其中Katana cookie管理器和ASP .NET cookie管理器冲突并覆盖彼此的cookie . 完整的详细信息和解决方法:
http://katanaproject.codeplex.com/wikipage?title=System.Web%20response%20cookie%20integration%20issues&referringTitle=Documentation
现在可以在Microsoft.Owin.Host.SystemWeb Nuget包中找到下面显示的SystemWebCookieManager .
添加CodePlex死亡时的代码:
我也是一个要点:https://gist.github.com/irwinwilliams/823f43ef8a5e8019a95874049dbb8b00
我遇到了这个问题并在互联网上应用了所有修复程序 . 他们都没有工作,然后我进去看了我的 Cookies . 这是巨大的 . Owin中间件正在截断它,然后[授权]属性无法验证身份 - >将用户发送到oidc - >身份好 - 重定向到客户端 - >截断cookie - >无法验证[授权] - >将用户发送到oidc - >等
修复程序位于Microsoft.Owin.Host.SystemWeb 3.1.0.0并使用SystemWebChunkingCookieManager .
它将分割cookie并将它们解析在一起 .
我没有完全描述的问题,但我确实在我的DEV机器上基于OpenId连接的登录期间有一个重定向循环 .
在我的情况下,这是一个简单的错误与cookie . 我通过HTTP访问受保护的URL . 确保您通过HTTPS访问依赖方的受保护URL .
一旦通过身份验证,身份验证cookie将仅通过HTTPS发送,这意味着当您通过HTTP访问受保护的URL时,浏览器将不会发送带有请求的身份验证cookie,因此服务器会将您视为未经身份验证 . 此时,服务器会将您重定向到auth服务器(您已经登录的位置) . Auth服务器会将您重定向回原始网址,从而确保重定向循环 .
在您的部署中绝不应该这样,因为如果您具有身份验证等功能,则应始终在应用中使用全SSL . 这降低了会话劫持的风险 .
我有完全相同的问题 . 由于其他依赖性,无法将URL从HTTP更改为HTTPS . 最后通过在global.asax.cs中添加session_start和session_end来解决
以下代码通过在Golbal.asax.cs文件中添加会话事件解决了我的问题 .
并通过在Startup.Auth.cs文件的public void ConfigureAuth(IAppBuilder app)方法中添加以下代码