2012-03-20 37 views
11

Tôi có một trang web là một bên dựa vào STS tùy chỉnh dựa trên WIF của chúng tôi. Gần đây, chúng tôi đã triển khai Bộ nhớ cache bảo mật như được mô tả ở đây: Azure/web-farm ready SecurityTokenCache. Sự khác biệt chính giữa việc thực hiện của chúng tôi và sự khác biệt được mô tả trong liên kết đó là chúng tôi sử dụng Azure AppFabric Caching làm cửa hàng sao lưu cho bộ nhớ cache bền, thay vì lưu trữ bảng. Điều này đã giúp chúng tôi giải quyết vấn đề cắt ngắn thẻ trên một số trình duyệt nhất định nhưng đã giới thiệu một vấn đề mới (Chúng tôi thấy vấn đề cắt ngắn chủ yếu trên các trang có cookie phân tích + google phân tích ngoài cookie fedauth). Chúng tôi hiện đang nhận ngoại lệ sau vài nghìn lần mỗi ngày:Mã thông báo bảo mật WIF Caching

System.IdentityModel.Tokens.SecurityTokenException 
ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context. 

System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a  SecurityToken. A token was not found in the token cache and no cookie was found in the context. 
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) 
    at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) 
    at Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) 
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) 

Ngoại lệ này dường như xảy ra trong vòng chuyển hướng, vì vậy chúng tôi sẽ thấy hàng trăm trong số đó trong khoảng thời gian 1-2 phút.

Tôi không thể định vị bất kỳ thông tin hữu ích nào trong khi nghiên cứu ngoại lệ. Nugget duy nhất nắm giữ bất kỳ hy vọng cho đến nay là ai đó nói rằng nó có thể liên quan đến đối tượng được lưu trữ hết hạn trước phiên.

Chúng tôi không thể tạo lại vấn đề nội bộ và chỉ biết nó tồn tại vì hàng nghìn mục điền vào bảng Elmah của chúng tôi. Bất kỳ trợ giúp hoặc thông tin chi tiết nào sẽ được đánh giá rất nhiều.

Chúng tôi đẩy ra ngoài những gì chúng tôi nghĩ có thể giúp giải quyết vấn đề (mã dưới đây) nhưng nó không có hiệu lực:

HttpContext.Current.Response.Cookies.Remove("FedAuth"); 
WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule; 
string signoutUrl = (WSFederationAuthenticationModule.GetFederationPassiveSignOutUrl(authModule.Issuer, authModule.Realm, null)); 
Response.Redirect(signoutUrl); 

Trả lời

0

này nên được thực hiện nếu số lượng khiếu nại trong các dấu hiệu hoặc tổng kích thước của mã thông báo quá lớn để được chuyển qua lại trong cookie. Nếu đó không phải là trường hợp, sau đó đơn giản hóa giải pháp của bạn và chỉ sử dụng cài đặt mặc định sử dụng cookie. Bạn shuold tuy nhiên, sử dụng chứng chỉ mã hóa cookie dựa, do đó, nó vẫn còn "trang trại thân thiện". Theo mặc định WIF sẽ enrcrypt bằng cách sử dụng DPAPI có ái lực máy.

+1

Chúng tôi đã triển khai bộ nhớ cache mã thông báo bảo mật vì tập hợp cookie của chúng tôi vượt quá giới hạn kích thước cookie là 4096 byte trong một số trình duyệt (safari, opera, v.v.). Nó đã được thực hiện để đáp ứng với một vấn đề cắt ngắn cookie. Chúng tôi cũng đã sử dụng mã hóa cookie dựa trên chứng chỉ. Bộ nhớ cache mã thông báo bảo mật là "phải" đối với chúng tôi và có hiệu quả mà chúng tôi đã hy vọng nhưng việc triển khai đã tạo ra ngoại lệ mới này. Vấn đề thực sự với ngoại lệ này là nó ném người dùng của chúng tôi vào vòng lặp chuyển hướng. – Jeff

1

Chúng tôi thấy lỗi chính xác này nếu bạn duyệt đến ứng dụng mới bắt đầu, trong khi trình duyệt của bạn vẫn giữ cookie từ phiên trước đó. Vì các cookie này là cookie phiên, bản sửa lỗi là đóng mọi cửa sổ trình duyệt và duyệt lại ứng dụng.

Ứng dụng của chúng tôi là ứng dụng web 'bình thường' chuyển hướng đến AD FS bằng WIF mà không có bất kỳ thứ gì trong bộ nhớ cache bảo mật đặc biệt, theo như tôi biết. Tuy nhiên, chúng tôi sử dụng 'chế độ phiên' cho cookie WIF (xem ví dụ "Your FedAuth Cookies on a Diet: IsSessionMode=true"), điều này làm cho cookie WIF nhỏ hơn rất nhiều.

+0

Vì vậy, làm thế nào chúng ta sẽ có thể repro này để chắc chắn nếu đây là vấn đề và làm thế nào chúng tôi sẽ ngăn chặn nó xảy ra? Tôi sẽ kiểm tra nhưng tôi tin rằng chúng tôi để cho một trình duyệt ngồi ở trang trong 24 giờ và sau đó làm mới để xem chúng tôi có thể làm cho nó để repro và nó sẽ không. Chúng ta phải đảm bảo rằng có một khởi động ứng dụng/khởi động lại là tốt? Tôi không chắc chắn 100% bởi những gì bạn có nghĩa là "một ứng dụng mới bắt đầu". –

1

Chúng tôi hiện đang đối mặt với cùng một vấn đề, mặc dù tình hình của chúng tôi hơi khác một chút. Chúng tôi đang cố gắng sử dụng WIF để cung cấp cho Shibboleth SSO cho Outlook Web App (OWA). Chúng tôi có một số máy chủ OWA phía sau bộ cân bằng tải.

WIF tạo cookie FedAuth (và FedAuth1) có kích thước lớn hơn 2,5 kB. Trình cân bằng tải của chúng tôi cắt cookie. Vì vậy, chúng tôi đặt IsSessionMode -Property thành đúng trong tệp global.asax của OWA. Bây giờ, kích thước cookie được giảm xuống còn xấp xỉ. 600 byte, đó là tốt. OWA hoạt động.

Tuy nhiên, Bảng điều khiển Exchange (ECP) chạy trên cùng một máy chủ, không hoạt động nữa. ECP chạy trong cùng một nhóm ứng dụng IIS và cũng có tập IsSessiobnMode-Property trong tập tin global.asax của nó. Bất cứ khi nào ECP được gọi, ứng dụng không gửi lại bất kỳ phản hồi nào nhưng báo cáo WIF:

Current user: 'User not set' 
    Request for URL 'http://owa.ourdomain.com/ecp/' failed with the following error: 
    System.IdentityModel.Tokens.SecurityTokenException: ID4243: Could not create a SecurityToken. A token was not found in the token cache and no cookie was found in the context. 
2

Vấn đề này gây ra do bộ nhớ đệm SessionSecurityToken.Điểm đến bộ nhớ cache nằm trong miền địa phương của nhóm ứng dụng, do đó khi bộ nhớ .NET cần, nó sẽ tự động bị xóa. Giải pháp tốt nhất là hai hủy bỏ bộ đệm ẩn để bảo mật hoặc triển khai hệ thống con của riêng bạn để lưu vào bộ nhớ đệm.

giải pháp 1

AppFabric cho Windows Server memcached - Hệ thống một phân phối bộ nhớ đối tượng bộ nhớ đệm

giải pháp 2

var sessionSecurityToken = new SessionSecurityToken(principal, TimeSpan.FromHours(Convert.ToInt32(System.Web.Configuration.WebConfigurationManager.AppSettings["SessionSecurityTokenLifeTime"]))) 
{ 
    IsPersistent = false, // Make persistent 
    IsReferenceMode = true // Cache on server 
}; 
FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken); 
5

Tôi có một ứng dụng trang duy nhất MVC như một bữa tiệc dựa sử dụng WSO2 4.5 như IDP và đã nhận được cùng một lỗi - "System.IdentityModel.Tokens.SecurityTokenException ID4243: Không thể tạo một SecurityToken. Một mã thông báo không được tìm thấy trong bộ nhớ cache mã thông báo và không có cookie được tìm thấy trong ngữ cảnh. ... "Đã tìm kiếm và tìm thấy các tuyên bố dưới đây của Brock Allen về sự nổi tiếng của Thinktecture.

Ngoại lệ này được ném khi trình duyệt gửi cookie có chứa khiếu nại của người dùng nhưng có điều gì đó về quá trình xử lý không thể được thực hiện (hoặc khóa đã thay đổi để mã thông báo không thể được xác thực hoặc nếu sử dụng bộ nhớ cache phía máy chủ và bộ nhớ cache trống). Người dùng cuối sẽ không thể thực hiện nhiều việc này và họ sẽ . tiếp tục nhận được lỗi từ trình duyệt sẽ tiếp tục gửi cookie

Full bài viết: http://brockallen.com/2012/10/22/dealing-with-session-token-exceptions-with-wif-in-asp-net/

Trong cùng một bài viết, ông cung cấp đoạn mã sau giải quyết vấn đề trong trường hợp của tôi. Trong Global.asax:

void Application_OnError() 
{ 
    var ex = Context.Error; 
    if (ex is SecurityTokenException) 
    { 
     Context.ClearError(); 
     if (FederatedAuthentication.SessionAuthenticationModule != null) 
     { 
      FederatedAuthentication.SessionAuthenticationModule.SignOut(); 
     } 
     Response.Redirect("~/"); 
    } 
} 
Các vấn đề liên quan