asp.net-mvc - 在 MVC3 中扩展 ClaimsIdentity

标签 asp.net-mvc asp.net-mvc-3 claims-based-identity

我已经使用 azure 使用 MVC3 设置了我的声明,并且一切顺利。

我现在需要做的是扩展当前线程/http上下文中的Claims Identity并添加我自己的信息(DOB,地址..之类的东西)

所以我的问题是 - 最好的地方在哪里?任何例子都会很棒..

我假设当用户通过身份验证时,必须去数据库并为用户拉回相关记录,然后将其添加到自定义 Claims Identity 对象中?

最佳答案

通常,您将有一个 httpmodule 来检查 cookie,一旦找到 FedAuth token ,您就有一个 Hook 来构建您的 Claims Principal 和身份。

您通常不需要存储用户的整个配置文件,只需存储通常不会经常更改的有用内容。我在 Action 过滤器中执行此操作。

这是我发现完成所有这些的代码。

https://github.com/wcpro/ScaffR/tree/master/src/ScaffR.Security/content/CodeTemplates/Scaffolders/ScaffR.Security

您可能需要进行一些挖掘,但一切都在那里。

这是http模块的代码

public class ClaimsTransformationHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostAuthenticateRequest += context_PostAuthenticateRequest;
    }

    void context_PostAuthenticateRequest(object sender, EventArgs e)
    {
        var context = ((HttpApplication) sender).Context;

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

    public void Dispose() { }
}

这是 claim 转换器
    public partial class ClaimsTransformer : ClaimsAuthenticationManager
{
    partial void SetCustomPrincipalClaims(IUserService userService, ref ClaimsPrincipal principal);

    public override ClaimsPrincipal Authenticate(string resourceName, ClaimsPrincipal incomingPrincipal)
    {
        if (!incomingPrincipal.Identity.IsAuthenticated)
        {
            return incomingPrincipal;
        }

        var newPrincipal = Transform(incomingPrincipal);

        EstablishSession(newPrincipal);

        return newPrincipal;
    }

    ClaimsPrincipal Transform(ClaimsPrincipal incomingPrincipal)
    {
        var nameClaim = incomingPrincipal.Identities.First().FindFirst(ClaimTypes.Name);

        var userService = DependencyResolver.Current.GetService<IUserService>();

        var user = userService.GetByUsername(nameClaim.Value);

        var id = new ApplicationIdentity(user);

        var principal = new ClaimsPrincipal(id);

        SetCustomPrincipalClaims(userService, ref principal);

        return principal;
    }        

    private void EstablishSession(ClaimsPrincipal principal)
    {
        if (HttpContext.Current != null)
        {
            var sessionToken = new SessionSecurityToken(principal);
            FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(sessionToken);
        }
    }
}

然后这里是配置
<?xml version="1.0" encoding="utf-8"?>
<system.identityModel>
  <identityConfiguration>
    <claimsAuthenticationManager type="Barbarella.Core.Common.Security.ClaimsTransformer, Barbarella.Core" />
  </identityConfiguration>
</system.identityModel>

还有这个...
    <system.identityModel.services>
  <federationConfiguration>
    <cookieHandler mode="Default" requireSsl="false" />
  </federationConfiguration>
</system.identityModel.services>

还有这个...
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
  <add name="ClaimsTransformationModule" type="Barbarella.Core.Common.Security.ClaimsTransformationHttpModule, Barbarella.Core" />
  <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

</modules>

不要忘记添加您的配置部分
    <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" />

这是我的 ApplicationIdentity 代码(覆盖 ClaimsIDentity)...这是真正回答您问题的代码...
 public sealed partial class ApplicationIdentity : ClaimsIdentity
{
    partial void SetCustomIdentityClaims(User user);

    private readonly User _user;

    public ApplicationIdentity(User user) : base("Application")
    {
        _user = user;
        AddClaim(new Claim(ClaimTypes.Name, user.Username));     
        AddClaim(new Claim(ApplicationClaimTypes.UserId, user.Id.ToString(CultureInfo.InvariantCulture)));
        AddClaim(new Claim(ApplicationClaimTypes.FirstName, user.FirstName));
        AddClaim(new Claim(ApplicationClaimTypes.LastName, user.LastName));
        AddClaim(new Claim("Time", DateTime.Now.ToString()));

        SetCustomIdentityClaims(_user);
    }

    public User User
    {
        get { return _user; }
    }

    public int UserId
    {
        get { return int.Parse(FindFirst(ApplicationClaimTypes.UserId).Value); }
    }

    public string Username
    {
        get { return FindFirst(ClaimTypes.Name).Value; }
    }

}

关于asp.net-mvc - 在 MVC3 中扩展 ClaimsIdentity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12385231/

相关文章:

c# - Quartz for asp.net 被 iis 服务器杀死

asp.net-mvc-3 - MVC找出当前Web请求是针对 Controller /操作还是静态资源

c# - 有效的 RegEx 不适用于 ASP.Net MVC RegularExpression 属性

c# - 如何在请求过滤器的 ViewResult 上设置 View 模型?

c# - 将值传递给 nlog 自定义目标

c# - DataAnnotations "NotRequired"属性

jquery - 使用 ajaxForm jQuery 插件时 IE 尝试下载 json 响应

c# - 如何对使用 FederatedAuthentication.SessionAuthenticationModule 的代码进行单元测试

asp.net-mvc-5 - MVC 5-向用户添加声明

angular - JWT Bearer ASP.Net Core 3.1 用户在服务器上为空