Asp.net MVC - 将声明身份映射到自定义用户身份

发布于 2024-12-06 23:41:28 字数 712 浏览 0 评论 0原文

在收到来自 Azure AccessControl Service 2.0 的声明身份验证后,我试图找出 ASP.NET MVC3 基础结构中映射自定义用户信息(从本地数据库加载)的最佳扩展点在哪里我

尝试通过覆盖 Authenticate 方法来实现此目的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 的较低级别的某个地方?

I'm trying to figure where is the best extension point in the ASP.NET MVC3 infrastructure to map custom user informations (loaded from local database) after received the Claim Authentication from Azure AccessControl Service 2.0

I tried to achieved this by overriding the Authenticate method of Microsoft.IdentityModel.Claims.ClaimsAuthenticationManager class :

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

However, it seems that this method is called more than once during the page loading request.
Loading custom user informations here could produce a performance issue.
I would like to load them only once per authenticated session.

Is there a better place to do that ?
Perhaps somewhere at a lower level where the IClaimsPrincipal is constructed ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

流云如水 2024-12-13 23:41:28

您只需要执行 isAuthenticated 检查:

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

这只会在用户首次通过身份验证后运行一次。

You just need to do an isAuthenticated check:

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

This will only run once after the user is first authenticated.

生死何惧 2024-12-13 23:41:28

仅当用户登录时运行一次。

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

This is only running once when the user is logging in.

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
            }
        }
    }
愛放△進行李 2024-12-13 23:41:28

任何非来自 STS 的用户信息都是有关用户的卫星数据。因此最好用 Asp .Net ProfileProvider 基础设施来表示这一点。

更新:

您可以做的另一件事是实现一个简单的自定义 STS,它将把来自数据库的自定义声明添加到传入的声明中。您的自定义 STS 将信任 ACS 并接受 SAML 令牌,并且您的 Web 应用程序将信任它。

另一件我没有尝试过的事情是试图篡改来自 STS 的声明。您可以尝试的一件事是注册到 WSFederationAuthenticationModule 的 SecurityTokenValidated 事件。在这种情况下,您可以尝试将其他声明添加到事件参数的 ClaimsPrincipal 中。

该事件应该在创建会话令牌之前引发,因此您应该在每次登录时查找数据库一次。

干杯,

Any user information which is not coming from the STS is satellite data about the user. So it would be best to represent this with Asp .Net ProfileProvider infrastructure.

Update:

Another thing which you can do is implemeting a simple Custom STS which will add your custom claims coming from your DB, into the incoming claims. Your Custom STS will trust ACS and will take SAML tokens, and it will be trusted by your web applition.

Another thing, which I haven't tried, would be attempting to tamper with the claims coming from STS. One thing which you can give a try is registering to the SecurityTokenValidated event of the WSFederationAuthenticationModule. In this event you can try to add your additional claims into ClaimsPrincipal of the event arg.

This event should be raised before the session token is created, so you sould be looking up db once per login.

cheers,

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文