Simple claims transformation and caching w/ windows authentication

前端 未结 2 582
名媛妹妹
名媛妹妹 2020-12-07 19:28

For the past few days I\'ve been reading about the windows identity foundation and how it\'s so good and flexible and built right into .net 4.5. Despite going over dozens of

2条回答
  •  眼角桃花
    2020-12-07 20:11

    I've got everything working now, here's how I went about it:

    On this page: http://msdn.microsoft.com/en-us/library/ee517293.aspx Was a key paragraph:

    If you want to make your RP application claims-aware, but you do not have an STS (for example, the RP uses Forms authentication or Windows integrated authentication), you can use the ClaimsPrincipalHttpModule. This module sits in your application’s HTTP pipeline and intercepts authentication information. It generates a IClaimsPrincipal for each user based on that user’s username, group memberships, and other authentication information. ClaimsPrincipalHttpModule must be inserted at the end of the pipeline, which is the first element in the section of on IIS 7.

    And this page:

    http://leastprivilege.com/2012/04/04/identity-in-net-4-5part-2-claims-transformation-in-asp-net-beta-1/

    Gives you the whole class:

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

    Now add that class to the web.config:

    
      
    
    

    Now it will call the transformation and I can remove the post authenticate method in global.asax.

    In the authenticate method, I call this to set the cookie:

    private void CreateSession(ClaimsPrincipal transformedPrincipal)
    {
        SessionSecurityToken sessionSecurityToken = new SessionSecurityToken(transformedPrincipal, TimeSpan.FromHours(8));
        FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionSecurityToken);
    }
    

    The module from before is already set up to look at it and skip authentication if it's present.

    Lastly for the safe handle error that I kept getting. I'm not exactly sure of the cause, but I discovered that if I modified the principal that gets passed to Authenticate and then returned it (which is what it shows on msdn), then the error would show up on all subsequent requests. However if I created and returned a new principal then it would not occur. This also turns out to be useful for dropping claims that you don't need.

    List newClaims = new List();
    
    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);
    

    So now I can windows authenticate, bring in custom claims, and have them cached with a cookie. Hope this helps anyone else trying to do the same and if I'm not doing something right please let me know.

提交回复
热议问题