2011-09-26 109 views
2

我試圖找出哪裏是ASP.NET MVC3基礎架構中的最佳擴展點,以便在接收到聲明身份驗證之後映射自定義用戶信息(從本地數據庫加載)從Azure的AccessControl的服務2.0Asp.net MVC - 映射要求自定義用戶身份的身份

我試圖通過覆蓋Microsoft.IdentityModel.Claims.ClaimsAuthenticationManager類的身份驗證方法來實現這一點:

public class ClaimsTransformationModule : ClaimsAuthenticationManager 
{ 
    public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal) 
    { 
     // Load User from database and map it to HttpContext 
     // Code here 

     return base.Authenticate(resourceName, incomingPrincipal); 
    } 
} 

然而,似乎這個方法是在調用一次以上頁面加載請求。 在此處加載自定義用戶信息可能會產生性能問題。 我想每個認證會話只加載一次。

有沒有更好的地方做到這一點? 也許某處IClaimsPrincipal構建的較低級別?

回答

2

你只需要做一個isAuthenticated檢查:

if (incomingPrincipal.Identity.IsAuthenticated) 
{ 
    // Load User from database and map it to HttpContext 
    // Code here 
} 

用戶首先通過身份驗證後,這將只運行一次。

+0

簡單而高效。非常感謝:) –

+1

把一個調試標記放在那個if語句裏,你會看到它不止一次運行。 –

+0

雖然這可行,但它會針對每個請求運行 – Rui

0

任何不是來自STS的用戶信息都是關於用戶的衛星數據。因此,最好用Asp.Net ProfileProvider基礎結構來表示這一點。

更新:

另一件事,你所能做的就是implemeting一個簡單的自定義STS這將增加從DB降臨到你的自定義聲明,到輸入索賠。您的自定義STS將信任ACS並將採用SAML令牌,並且您的Web應用程序將信任它。

另一件我沒有試過的東西,會試圖篡改STS的聲稱。您可以嘗試的一件事是註冊到WSFederationAuthenticationModule的SecurityTokenValidated事件。在此事件中,您可以嘗試將其他聲明添加到事件參數的ClaimsPrincipal中。

這個事件應該在創建會話標記之前提出,所以你應該在每次登錄時查找一次db。

歡呼聲,

+0

我的問題是關於身份。 ProfileProvider用於存儲用戶數據而非身份。你可能會談論MembershipProvider。我想知道的是,我可以在聲明接收流程中插入自定義用戶(IIdentity,IPrincipal)。 –

+0

用戶身份由ACS信任的第三方身份提供商驗證。然後,ACS作爲安全令牌服務器將此身份打包到令牌中,並將其發送給您的應用程序。在這方面,用戶的身份理想情況下應該來自可信的STS,ACS。 如果您希望將其他聲明添加到用戶身份,則正確的方法是添加一個與ACS(WS Federation Server)具有信任關係的自定義STS,然後從您的RP應用程序信任該自定義STS。 – Atacan

1

這當用戶在登錄只運行一次。

public class MvcApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      WebApiConfig.Register(GlobalConfiguration.Configuration); 
      FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 
      AuthConfig.RegisterAuth(); 
      FederatedAuthentication.WSFederationAuthenticationModule.SecurityTokenValidated += WSFederationAuthenticationModule_SecurityTokenValidated; 
     } 

     void WSFederationAuthenticationModule_SecurityTokenValidated(object sender, SecurityTokenValidatedEventArgs e) 
     { 
      IClaimsPrincipal principal = e.ClaimsPrincipal; 
      IClaimsIdentity identity = (IClaimsIdentity)principal.Identity; 

      try 
      { 
       //SQL connection/Claims injeciotn 
       if (principal.Identity.IsAuthenticated) 
       { 
        // identity.Claims.Add(new Claim(ClaimTypes.Role, "WebAdmins")); 
       } 

      } 
      catch 
      { 
       //Error 
      } 
     } 
    }