2

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

我试图通过覆盖 Microsoft.IdentityModel.Claims.ClaimsAuthenticationManager 类的 Authenticate 方法来实现这一点:

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 的较低级别的某个地方?

4

3 回答 3

2

你只需要做一个isAuthenticated检查:

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

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

于 2011-09-27T22:31:27.553 回答
1

这仅在用户登录时运行一次。

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
            }
        }
    }
于 2012-09-24T05:04:01.800 回答
0

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

更新:

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

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

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

干杯,

于 2011-09-26T22:49:22.837 回答