Dot-Net

帶有 Windows 身份驗證的簡單聲明轉換和記憶體

  • November 15, 2018

在過去的幾天裡,我一直在閱讀有關 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:

&lt;modules&gt;
 &lt;add name="ClaimsTransformationHttpModule" type="TestSecurity.ClaimsTransformationHttpModule" /&gt;
&lt;/modules&gt;

現在它將呼叫轉換,我可以刪除 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&lt;Claim&gt; newClaims = new List&lt;Claim&gt;();

var keeper = ((ClaimsIdentity)incomingPrincipal.Identity).Claims.First(c =&gt;
   c.Type == ClaimTypes.Name);
newClaims.Add(keeper);

ClaimsIdentity ci = new ClaimsIdentity(newClaims, "Negotiate");

return new ClaimsPrincipal(ci);

所以現在我可以對 Windows 進行身份驗證,引入自定義聲明,並將它們與 cookie 一起記憶體。希望這可以幫助其他嘗試做同樣的事情的人,如果我做的不對,請告訴我。

引用自:https://stackoverflow.com/questions/16904639