帶有 Windows 身份驗證的簡單聲明轉換和記憶體
在過去的幾天裡,我一直在閱讀有關 windows 身份基礎以及它如何如此出色和靈活並直接內置到 .net 4.5 中的資訊。儘管瀏覽了數十個 api、部落格文章、操作方法等。我一生都無法獲得一個簡單的實現工作。
我只使用 Windows 身份驗證,我可以獲取主體並查看它附帶的聲明(這是每個範例似乎結束的地方)。但是,我想將它們轉換為有用的聲明並記憶體結果,以便轉換不會發生在每個請求上。
在我的 web.config 中,我有:
<configSections> <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> </configSections> <system.identityModel> <identityConfiguration> <claimsAuthenticationManager type="SecurityProj.MyClaimsTransformationModule,SecurityProj" /> <claimsAuthorizationManager type="SecurityProj.MyClaimsAuthorizationManager,SecurityProj" /> </identityConfiguration> </system.identityModel>但是,身份驗證管理器永遠不會被呼叫。我可以讓它工作的唯一方法是添加:
protected void Application_PostAuthenticateRequest() { ClaimsPrincipal currentPrincipal = ClaimsPrincipal.Current; ClaimsTransformationModule customClaimsTransformer = new MyClaimsTransformationModule(); ClaimsPrincipal tranformedClaimsPrincipal = customClaimsTransformer.Authenticate(string.Empty, currentPrincipal); HttpContext.Current.User = tranformedClaimsPrincipal; }到我的 global.asax.cs 文件。它適用於第一個請求,但之後我收到“安全句柄已關閉”錯誤並且不知道是什麼原因造成的。顯然這不是正確的方法,所以有人知道什麼是最佳或簡單的工作實踐嗎?這只是用於 Windows 身份驗證,我不需要比這更複雜的任何東西。
對於記憶體,我試圖使用:
SessionSecurityToken token = FederatedAuthentication.SessionAuthenticationModule .CreateSessionSecurityToken( currentPrincipal, "Security test", System.DateTime.UtcNow, System.DateTime.UtcNow.AddHours(1), true); if (FederatedAuthentication.SessionAuthenticationModule != null && FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(HttpContext.Current.Request.Cookies)) { return; } FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(token);但我也不確定那部分,轉換問題需要先解決。
任何幫助,將不勝感激。只需要呼叫查找/轉換和 cookie 集,謝謝。
我現在一切正常,這就是我的做法:
在此頁面上:http: //msdn.microsoft.com/en-us/library/ee517293.aspx是關鍵段落:
如果您想讓您的 RP 應用程序具有聲明感知功能,但您沒有 STS(例如,RP 使用 Forms 身份驗證或 Windows 集成身份驗證),則可以使用 ClaimsPrincipalHttpModule。該模組位於應用程序的 HTTP 管道中並攔截身份驗證資訊。它根據使用者的使用者名、組成員身份和其他身份驗證資訊為每個使用者生成一個 IClaimsPrincipal。ClaimsPrincipalHttpModule 必須插入到
<httpModules>管道的末尾,這是IIS 7<modules>部分中的第一個元素。<system.webServer>這個頁面:
<http://leastprivilege.com/2012/04/04/identity-in-net-4-5part-2-claims-transformation-in-asp-net-beta-1/>
給你全班:
public class ClaimsTransformationHttpModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication context) { context.PostAuthenticateRequest += Context_PostAuthenticateRequest; } void Context_PostAuthenticateRequest(object sender, EventArgs e) { var context = ((HttpApplication)sender).Context; // no need to call transformation if session already exists if (FederatedAuthentication.SessionAuthenticationModule != null && FederatedAuthentication.SessionAuthenticationModule.ContainsSessionTokenCookie(context.Request.Cookies)) { return; } var transformer = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager; if (transformer != null) { var transformedPrincipal = transformer.Authenticate(context.Request.RawUrl, context.User as ClaimsPrincipal); context.User = transformedPrincipal; Thread.CurrentPrincipal = transformedPrincipal; } } }現在將該類添加到 web.config:
<modules> <add name="ClaimsTransformationHttpModule" type="TestSecurity.ClaimsTransformationHttpModule" /> </modules>現在它將呼叫轉換,我可以刪除 global.asax 中的 post authenticate 方法。
在 authenticate 方法中,我呼叫它來設置 cookie:
private void CreateSession(ClaimsPrincipal transformedPrincipal) { SessionSecurityToken sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8)); FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken); }之前的模組已經設置為查看它並跳過身份驗證(如果存在)。
最後是我不斷收到的安全處理錯誤。我不確定原因,但我發現如果我修改了傳遞給 Authenticate 然後返回它的主體(這是它在 msdn 上顯示的內容),那麼該錯誤將出現在所有後續請求中。但是,如果我創建並返回了一個新的主體,那麼它就不會發生。事實證明,這對於放棄不需要的聲明也很有用。
List<Claim> newClaims = new List<Claim>(); var keeper = ((ClaimsIdentity)incomingPrincipal.Identity).Claims.First(c => c.Type == ClaimTypes.Name); newClaims.Add(keeper); ClaimsIdentity ci = new ClaimsIdentity(newClaims, "Negotiate"); return new ClaimsPrincipal(ci);所以現在我可以對 Windows 進行身份驗證,引入自定義聲明,並將它們與 cookie 一起記憶體。希望這可以幫助其他嘗試做同樣的事情的人,如果我做的不對,請告訴我。