使用 Windows 身份验证的简单声明转换和缓存 [英] Simple claims transformation and caching w/ windows authentication

查看:18
本文介绍了使用 Windows 身份验证的简单声明转换和缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几天里,我一直在阅读有关 windows 身份基础以及它如何如此出色和灵活并直接内置到 .net 4.5 中的内容.尽管浏览了数十个 api、博客文章、操作方法等.我终生无法获得一个简单的实现.

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 apis, blog posts, how-to's etc. I can't for the life of me get a simple implementation working.

我只使用 Windows 身份验证,我可以获得主体并查看它附带的声明(每个示例似乎都在这里结束).但是,我想然后将它们转换为有用的声明并缓存结果,这样转换就不会在每个请求中都发生.

I'm using windows authentication only and I can get the principal and view the claims that come with it (which is where every example seems to end). However I want to then transform them into useful claims and cache the results so that the transformation doesn't happen on every single request.

在我的 web.config 中,我有:

In my web.config I have:

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

然而,身份验证管理器永远不会被调用.我可以让它工作的唯一方法是添加:

However the authentication manager never gets called. The only way I can get it to sort of work is by adding:

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 身份验证,我不需要任何比这更复杂的东西.

To my global.asax.cs file. It works on the first request but then I get "Safe handle has been closed" errors after that and have no idea what is causing it. Clearly this isn't the correct way to do it, so does anyone know what a best or simply working practice is? This is just for windows authentication, I don't need anything more complicated than that.

对于缓存,我试图使用:

For the caching, I was trying to use:

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

但我也不确定那部分,需要先解决转换问题.

but I'm not sure about that part either and the transformation problems need to be fixed first.

任何帮助将不胜感激.只需要调用查找/转换和设置 cookie,谢谢.

Any help would be appreciated. Just need the lookup/transform to be called and a cookie set, thanks.

推荐答案

我现在一切正常,我是这样处理的:

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

在此页面上:http://msdn.microsoft.com/en-us/library/ee517293.aspx 是一个关键段落:

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

如果您想让您的 RP 应用程序声明感知,但您没有 STS(例如,RP 使用表单身份验证或 Windows 集成身份验证),您可以使用 ClaimsPrincipalHttpModule.该模块位于应用程序的 HTTP 管道中并拦截身份验证信息.它根据每个用户的用户名、组成员身份和其他身份验证信息为每个用户生成一个 IClaimsPrincipal.ClaimsPrincipalHttpModule 必须插入到 管道的末尾,它是 部分的第一个元素; 在 IIS 7 上.

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 <httpModules> pipeline, which is the first element in the <modules> section of <system.webServer> on IIS 7.

还有这个页面:

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:

Now add that class to the web.config:

<modules>
  <add name="ClaimsTransformationHttpModule" type="TestSecurity.ClaimsTransformationHttpModule" />
</modules>

现在它将调用转换,我可以删除 global.asax 中的 post 验证方法.

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

在身份验证方法中,我调用它来设置 cookie:

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.

最后是我不断收到的安全句柄错误.我不完全确定原因,但我发现如果我修改了传递给 Authenticate 然后返回它的主体(这是它在 msdn 上显示的内容),那么错误将出现在所有后续请求中.但是,如果我创建并返回了一个新的主体,那么它就不会发生.事实证明,这对于删除您不需要的声明也很有用.

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

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

所以现在我可以进行 Windows 身份验证,引入自定义声明,并使用 cookie 缓存它们.希望这可以帮助其他人尝试做同样的事情,如果我做的不对,请告诉我.

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.

这篇关于使用 Windows 身份验证的简单声明转换和缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆