2015-07-31 18 views
23

bài đăng đầu tiên rất nhẹ nhàng! :)Lần đăng nhập thứ hai gây ra vòng lặp chuyển hướng vô hạn sau lần đăng nhập thành công đầu tiên MVC .NET 5 OWIN ADAL OpenIDConnect

Tôi đang phát triển ứng dụng web MVC .NET 5 cho Office 365 và đang sử dụng khung công tác OpenIDConnect. Tôi đã thiết lập OWIN (3) và ADAL (2) và Ứng dụng Azure AD của tôi. Không có người dùng đăng nhập hành động, bộ điều khiển nhà có thuộc tính [Authorize] được đính kèm, buộc chuyển hướng đăng nhập ngay lập tức vào Azure AD. Tôi không sử dụng vai trò trong bất kỳ thuộc tính ủy quyền nào của tôi.

Sự cố: Tôi có thể đăng nhập vào các ứng dụng của mình thành công - ONCE! Sau lần đăng nhập đầu tiên, tôi đóng trình duyệt (hoặc mở một trình duyệt mới trên một máy khác) và tôi nhấn lại ứng dụng. Nó chuyển hướng tôi đến màn hình đăng nhập Azure AD mà tôi đăng nhập và sau đó nó liên tục chuyển hướng giữa ứng dụng và Azure cho đến khi tôi nhận được 400 tiêu đề khét tiếng về vấn đề lâu dài. Nhìn vào cửa hàng bánh quy, tôi thấy rằng nó chứa đầy vô số. Tôi kiểm tra cache (công thức EFADALCache của Vittorio, mặc dù tôi đã sử dụng TokenCache.DefaultShared khi phát hiện vấn đề này) và nó có hàng trăm hàng dữ liệu cache (Chỉ có một hàng được tạo với đăng nhập thành công).

tôi có thể thấy như chuyển hướng xảy ra qua cửa sổ ra rằng một truy cập mới và mã thông báo làm mới được tạo ra mỗi chuyến đi vòng:

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= 

Thông báo AuthorizationCodeReceived trong OpenIdConnectAuthenticationOptions của tôi là bị trúng khi vấn đề đang xảy ra , vì vậy tôi biết rằng Azure nghĩ đăng nhập thành công (hoặc nếu không chuyển hướng trở lại ứng dụng sẽ không xảy ra):

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); 
        } 
       } 
      }); 
    } 
} 

tôi đã thay thế (sau khi phát hiện vấn đề) thuộc tính ủy quyền với Auth của riêng tôi thuộc tính, kế thừa từ AuthorizeAttribute, chỉ vì vậy tôi có thể thử và bước vào mã Ủy quyền và xem điều gì đang xảy ra. Tôi xây dựng một tập tin PDB từ phiên bản 5 của mã nguồn MVC 5, nhưng tất cả những gì xảy ra là nó nhảy trở lại vào mã của riêng tôi: (Điều đó được nói, tôi đã ghi đè những gì tôi có thể và đã tìm thấy rằng filterContext.HttpContext .User.Identity.IsAuthenticated là sai, có ý nghĩa, vì điều đó sẽ gây ra sự chuyển hướng trở lại dấu Azure trong

vì vậy, tôi biết rằng:.

  • Azure được chấp nhận đăng nhập của tôi và trả lại mã thông báo có liên quan
  • Lần đăng nhập thứ hai, trước khi OnAuthorization, filterContext.HttpContext.User.Identity.IsAuthenticated trả về false
  • cấu hình ứng dụng Azure của tôi là tốt, hoặc nó sẽ không xác thực ở tất cả

Tôi nghĩ rằng:

  • Có cái gì đó trong cài đặt MVC nhận dạng đó là sai. Azure đang hoạt động chính xác hoặc không xác thực.
  • Nó không phải là một vấn đề Cookie là vấn đề phát sinh nếu bạn thực hiện việc đăng nhập thứ hai trên một máy khác nhau

Tôi xin lỗi này là một chút dài dòng, nhưng có rất nhiều những vấn đề chuyển hướng vô hạn ngoài kia, tôi cần giải thích tại sao tình hình của tôi lại khác!

Điều tôi đang tìm kiếm (nếu không phải là câu trả lời!) là một bước đi đúng hướng về cách tôi có thể gỡ lỗi thêm.

Đánh giá cao bất kỳ trợ giúp nào bạn có thể cung cấp!

Andy

+4

Đã tìm thấy câu trả lời cho bất kỳ ai quan tâm. Đó là một lỗi đã biết trong Katana, nơi quản lý cookie Katana và trình quản lý cookie ASP .NET xung đột và ghi đè lên các cookie của nhau. Chi tiết đầy đủ và giải pháp tại đây: http://katanaproject.codeplex.com/wikipage?title=System.Web%20response%20cookie%20integration%20issues&referringTitle=Documentation –

+0

Có vẻ như vấn đề này sẽ không được khắc phục trong ASP. NET 4, vì nó vẫn là một vấn đề ngày hôm nay. @AndyBullivent xin vui lòng đặt bình luận của bạn như là một câu trả lời. –

Trả lời

1

Tôi không có vấn đề chính xác mô tả, nhưng tôi đã có một vòng lặp chuyển hướng trong OpenID Connect dựa signin cũng trên máy DEV tôi.

Trong trường hợp của tôi, đó là lỗi đơn giản với cookie. Tôi đã truy cập URL được bảo vệ qua HTTP. Đảm bảo rằng bạn đang truy cập URL được bảo vệ trên bên dựa vào của bạn thông qua HTTPS.

Khi bạn được xác thực, cookie xác thực sẽ chỉ được gửi qua HTTPS, điều này có nghĩa là khi bạn truy cập URL được bảo vệ qua HTTP, trình duyệt sẽ không gửi cookie xác thực của bạn theo yêu cầu và do đó máy chủ sẽ thấy bạn là chưa được xác thực. Tại máy chủ điểm này sẽ chuyển hướng bạn đến máy chủ auth (nơi bạn đã đăng nhập). Máy chủ Auth sẽ chuyển hướng bạn trở lại url gốc, do đó đảm bảo vòng lặp chuyển hướng.

Điều này không bao giờ xảy ra trong trường hợp triển khai của bạn vì bạn luôn sử dụng tất cả SSL trong ứng dụng của mình, nếu bạn có các tính năng như xác thực. Điều này làm giảm nguy cơ bị chiếm đoạt phiên.

16

Đã tìm thấy câu trả lời cho bất kỳ ai quan tâm. Đó là một lỗi đã biết trong Katana, nơi quản lý cookie Katana và trình quản lý cookie ASP .NET xung đột và ghi đè lên các cookie của nhau. Chi tiết đầy đủ và cách giải quyết ở đây:

http://katanaproject.codeplex.com/wikipage?title=System.Web%20response%20cookie%20integration%20issues&referringTitle=Documentation

Các SystemWebCookieManager hiển thị dưới đây bây giờ có thể được tìm thấy trong gói Microsoft.Owin.Host.SystemWeb NuGet.

Thêm mã cho khi CodePlex chết:

//stick this in public void ConfigureAuth(IAppBuilder app) 
    app.UseCookieAuthentication(new CookieAuthenticationOptions 
      { 
       // ... 
       CookieManager = new SystemWebCookieManager() 
      }); 

//And create this class elsewhere: 
public class SystemWebCookieManager : ICookieManager 
    { 
     public string GetRequestCookie(IOwinContext context, string key) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException("context"); 
      } 

      var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 
      var cookie = webContext.Request.Cookies[key]; 
      return cookie == null ? null : cookie.Value; 
     } 

     public void AppendResponseCookie(IOwinContext context, string key, string value, CookieOptions options) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException("context"); 
      } 
      if (options == null) 
      { 
       throw new ArgumentNullException("options"); 
      } 

      var webContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); 

      bool domainHasValue = !string.IsNullOrEmpty(options.Domain); 
      bool pathHasValue = !string.IsNullOrEmpty(options.Path); 
      bool expiresHasValue = options.Expires.HasValue; 

      var cookie = new HttpCookie(key, value); 
      if (domainHasValue) 
      { 
       cookie.Domain = options.Domain; 
      } 
      if (pathHasValue) 
      { 
       cookie.Path = options.Path; 
      } 
      if (expiresHasValue) 
      { 
       cookie.Expires = options.Expires.Value; 
      } 
      if (options.Secure) 
      { 
       cookie.Secure = true; 
      } 
      if (options.HttpOnly) 
      { 
       cookie.HttpOnly = true; 
      } 

      webContext.Response.AppendCookie(cookie); 
     } 

     public void DeleteCookie(IOwinContext context, string key, CookieOptions options) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException("context"); 
      } 
      if (options == null) 
      { 
       throw new ArgumentNullException("options"); 
      } 

      AppendResponseCookie(
       context, 
       key, 
       string.Empty, 
       new CookieOptions 
       { 
        Path = options.Path, 
        Domain = options.Domain, 
        Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc), 
       }); 
     } 
    } 

tôi đã thực hiện một ý chính của nó, quá: https://gist.github.com/irwinwilliams/823f43ef8a5e8019a95874049dbb8b00

+0

Thx !! Hoàn toàn giải quyết được vấn đề của tôi! Tôi có dự án MVC với middleware owin auth, auth cookie đầu tiên sau đó oidc. Ngay sau khi tôi đặt thuộc tính ủy quyền trên bất cứ điều gì tôi sẽ nhận được vòng lặp vô hạn và tôi có thể thấy auth cookie nhập ResponseSignedIn. Có vẻ như System.Web đã thay thế cookie. Tôi đăng ký ra khỏi phiên proc và đọc phiên đó rất có thể là một người phạm tội ... anyways thx một lần nữa! –

+0

Hai ngón chân lên cuộc sống tiết kiệm ... Cảm ơn – Whoever

+0

Thx Tôi đang cấu trúc với những cho tuần trước.Now nó làm việc tốt :) – Jayendran

0

Tôi có chính xác cùng một vấn đề. Could'nt thay đổi url từ HTTP thành HTTPS do khác dependencies.Finally giải quyết bằng cách thêm session_start và session_end trong global.asax.cs

protected void Session_Start(object sender, EventArgs e) 
     { 
      // event is raised each time a new session is created  
     } 

    protected void Session_End(object sender, EventArgs e) 
     { 
      // event is raised when a session is abandoned or expires 

     } 
1

tôi gặp phải vấn đề này và áp dụng tất cả các bản sửa lỗi trên internet. Không ai trong số họ làm việc, sau đó tôi đã đi vào và nhìn vào cookie của tôi. Nó rất lớn. Phần mềm trung gian của Owin đã cắt xén và sau đó thuộc tính [Authorize] không thể xác minh danh tính -> gửi người dùng đến oidc -> danh tính tốt - chuyển hướng đến khách hàng -> cắt cookie -> không thể xác minh trong [Ủy quyền] - > gửi người dùng đến oidc -> v.v.

Bản sửa lỗi nằm trong Microsoft.Owin.Host.SystemWeb 3.1.0.0 và sử dụng SystemWebChunkingCookieManager.

Nó sẽ chia nhỏ các cookie và phân tích chúng lại với nhau.

app.UseCookieAuthentication(new CookieAuthenticationOptions 
    { 
     AuthenticationType = "Cookies", 
     CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager() 
    }); 
0

Mã dưới đây giải quyết được sự cố của tôi bằng cách thêm sự kiện phiên trong tệp Golbal.asax.cs.

protected void Session_Start(object sender, EventArgs e) 
    { 
     // event is raised each time a new session is created  
    } 



protected void Session_End(object sender, EventArgs e) 
    { 
     // event is raised when a session is abandoned or expires 

    } 

Và bằng cách thêm mã bên dưới vào khoảng trống công khai ConfigureAuth (ứng dụng IAppBuilder) phương pháp Startup.Auth.cs file

app.UseCookieAuthentication(new CookieAuthenticationOptions 
     { 
      AuthenticationType = "Cookies", 
      CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager() 
     }); 
Các vấn đề liên quan