Asp.net MVC — сопоставление удостоверения утверждения с пользовательским удостоверением пользователя

Я пытаюсь выяснить, где находится наилучшая точка расширения в инфраструктуре ASP.NET MVC3 для сопоставления пользовательской информации о пользователе (загруженной из локальной базы данных) после получения проверки подлинности утверждения от службы Azure AccessControl 2.0.

Я попытался добиться этого, переопределив метод 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?


person A. M.    schedule 26.09.2011    source источник


Ответы (3)


Вам просто нужно сделать isAuthenticated проверку:

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

Это будет выполняться только один раз после первой аутентификации пользователя.

person oaksinger    schedule 27.09.2011
comment
Просто и эффективно. Большое спасибо :) - person A. M.; 30.09.2011
comment
Поставьте метку отладки внутри этого оператора if, и вы увидите, что он выполняется более одного раза. - person Poul K. Sørensen; 24.09.2012

Это выполняется только один раз, когда пользователь входит в систему.

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
            }
        }
    }
person Poul K. Sørensen    schedule 24.09.2012

Любая информация о пользователе, не поступающая от STS, представляет собой спутниковые данные о пользователе. Поэтому было бы лучше представить это с помощью инфраструктуры Asp .Net ProfileProvider.

Обновление:

Еще одна вещь, которую вы можете сделать, — это реализовать простую пользовательскую STS, которая добавит ваши пользовательские утверждения, поступающие из вашей БД, во входящие утверждения. Ваша пользовательская STS будет доверять ACS и будет принимать токены SAML, и ваше веб-приложение будет доверять ей.

Еще одна вещь, которую я не пробовал, - это попытка подделать заявления, исходящие от STS. Вы можете попробовать зарегистрироваться в событии SecurityTokenValidated модуля WSFederationAuthenticationModule. В этом случае вы можете попытаться добавить свои дополнительные претензии в ClaimsPrincipal события arg.

Это событие должно быть вызвано до того, как будет создан токен сеанса, поэтому вы должны искать базу данных один раз при входе в систему.

ваше здоровье,

person Atacan    schedule 26.09.2011
comment
Мой вопрос об идентичности. ProfileProvider предназначен для хранения пользовательских данных, а не идентификационных данных. Вы, наверное, говорите о MembershipProvider. Я пытаюсь понять, где я могу подключить своего пользовательского пользователя (IIdentity, IPrincipal) к потоку приема претензий. - person A. M.; 27.09.2011
comment
Идентификация пользователя проверяется сторонним поставщиком удостоверений, которому доверяет ACS. Затем ACS, поскольку Secure Token Server упаковывает этот идентификатор в токен и отправляет его вашему приложению. В этом аспекте идентификация пользователя в идеале должна исходить только от доверенной STS, ACS. Если вы хотите добавить дополнительные утверждения в удостоверение пользователя, правильный способ сделать это — добавить пользовательскую службу STS, которая имеет доверительные отношения с ACS (сервером федерации WS), а затем доверить свое приложение RP этой пользовательской службе STS. - person Atacan; 27.09.2011