具有Windows身份验证的SessionAuthenticationModule

时间:2014-03-20 20:22:03

标签: c# asp.net asp.net-mvc wif claims-based-identity

我正在使用Windows身份验证,因为我的ASP.NET MVC 5应用程序在Intranet中运行(Active Directory是主要声明发布者)。

由于AD和浏览器在每次请求时都持续401握手,因此网站速度相当慢。

我现在正在研究一种缓存从AD收到的声明的方法,以获得一些性能提升。

这是否适用于WIF和SessionAuthenticationModule?一旦生成SessionSecurityToken,它是否会停止对AD的后续请求?在ASP.NET管道中创建这样一个令牌的最佳位置是什么?

1 个答案:

答案 0 :(得分:1)

  1. 是的,它可以用SAM
  2. 是的,您不必在初次转换后每次都达到AD

  3. 你应该做的就是这个

    1. 在您的网站上实施ClaimsAuthenticationManager。这将截取您的第一个请求并接收您的初始ClaimsPrincipal。最初的ClaimsPrincipal将只包含您的用户名和AD组的SID。

    2. 在您的ClaimsAuthenticationManager实现中,您将从AD中读出您的特定于应用程序的声明并创建一个新的转换的ClaimsPrincipal。然后将其序列化为Auth Cookie。

    3. 后续请求将被SAM截获,您不需要像第一次那样从AD进行索赔转换。

    4. 您就是这样做的:

      1. 创建一个ClaimsAuthenticationManager,如下所示:

        public class AdClaimsAppender : ClaimsAuthenticationManager
          {
            public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
        {
              if (!incomingPrincipal.Identity.IsAuthenticated)
              {
                  return base.Authenticate(resourceName, incomingPrincipal);
              }
              var adClaims = GetExtraAdClaims(incomingPrincipal);
              var newClaimsIdentity = new ClaimsIdentity(adClaims, "Windows");
              var newClaimsPrincipal = new ClaimsPrincipal(newClaimsIdentity);
             return base.Authenticate(resourceName, newClaimsPrincipal);
        }
        

        } }

      2. 将SAM模块添加到您的网络配置

            <system.webServer>
            <modules>
            <add name="SessionAuthenticationModule"
                    type="System.IdentityModel.Services.SessionAuthenticationModule,  System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral,  PublicKeyToken=b77a5c561934e089" preCondition="managedHandler"/>
             </modules>
            </system.webServer>
        
      3. 在全局asax中设置SAM Cookie

        using System.IdentityModel.Services;
         using System.IdentityModel.Services.Configuration;
        
        
        public class MvcApplication : HttpApplication
        {
            protected void Application_Start()
          {
              AreaRegistration.RegisterAllAreas();
              RouteConfig.RegisterRoutes(RouteTable.Routes);
                FederatedAuthentication.FederationConfigurationCreated += FederatedAuthentication_FederationConfigurationCreated;
          }
        
        private static void FederatedAuthentication_FederationConfigurationCreated(object sender, FederationConfigurationCreatedEventArgs e)
        {
            //from appsettings...
            const string domain = "";
            const bool requireSsl = false;
            const string authCookieName = "YourSiteAuth"; //default is fedauth, i normally create my own name as it is easier to identify when you have a lot of cookies.
        
            e.FederationConfiguration.CookieHandler = new ChunkedCookieHandler
                {
                    Domain = domain,
                    Name = authCookieName,
                    RequireSsl = requireSsl,
                    PersistentSessionLifetime = new TimeSpan(0, 0, 30, 0)
                };
        }