Asp.net MVC - 映射要求自定义用户身份的身份

Asp.net MVC - 映射要求自定义用户身份的身份

问题描述:

我试图找出哪里是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构建的较低级别?

你只需要做一个isAuthenticated检查:

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

用户首先通过身份验证后,这将只运行一次。

+0

简单而高效。非常感谢:) –

+1

把一个调试标记放在那个if语句里,你会看到它不止一次运行。 –

+0

虽然这可行,但它会针对每个请求运行 – Rui

任何不是来自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

这当用户在登录只运行一次。

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