Простое преобразование требований для RP-STS в Женевской системе
-
03-07-2019 - |
Вопрос
После прочтения статьи MSDN (http://msdn.microsoft.com/en-us/magazine/2009.01.genevests.aspx) при реализации пользовательского STS с использованием Microsoft Geneva Framework я немного озадачен одним из описанных там сценариев.Этот сценарий показан на рисунке 13 из вышеупомянутой статьи.
Мои вопросы касаются того, как RP инициирует вызов RP-STS, чтобы передать уже полученные утверждения от IP-STS?Как желаемый метод DeleteOrder() превращается в запрос утверждения для требования действия от RP-STS, который отвечает требованием действия со значением Delete, которое разрешает вызов?Я также думаю, что цифра немного неверна в том смысле, что взаимодействие между RP-STS и Механизмом политики должно иметь Утверждения и стрелки наоборот.
Я вижу структуру, но неясно, что предоставляется Geneva / WCF и что должно быть сделано в коде внутри RP, что показалось бы немного странным, поскольку мы не могли бы защитить метод DeleteOrder запросом PrincipalPermission на удаление "разрешения", но сначала должны были бы потребовать роль, а затем получить детализированное утверждение о действии удаления после этого момента.
Если я упустил суть (поскольку я не могу легко найти описание этого случая в Интернете), то приношу свои извинения!
Заранее благодарю.
Решение
Я задал тот же вопрос на Женевском форуме в http://social.msdn.microsoft.com/Forums/en/Geneva/thread/d10c556c-1ec5-409d-8c25-bee2933e85ea?prof=required и получил такой ответ:
Привет, Доки,
Я задавался тем же вопросом, когда читал эту статью.Пока я размышлял о том, как такой сценарий мог бы быть реализован, мне в голову пришли две идеи:
RP фактически настроен так, чтобы требовать утверждения от RP-STS;RP-STS требует токен безопасности от IP-STS.В результате, когда субъект запрашивает ресурс RP, он перенаправляет его RP-STS, который перенаправляет его на IP-STS.После аутентификации там он возвращается обратно в RP-STS, утверждения, ориентированные на идентификацию, преобразуются в те, которые необходимы для принятия решения об авторизации, и возвращаются в RP.
RP настроен на наличие перехватчика (например, AuthorizationPolicy, если это служба WCF), который перехватывает вызов, видит утверждения, ориентированные на идентификацию, создает RST (используя WSTrustClient), передает его RP-STS, эта служба расширяет утверждения до новых, которые возвращаются RP, и RP принимает решение об авторизации.
Я никогда не реализовывал это, но, если бы собирался, я бы изучил эти две идеи подробнее.
ХТХ!
С уважением,
Трэвис Спенсер
Поэтому сначала я попробую вариант 2 и посмотрю, сработает ли это, а затем сформулирую ответ здесь.
Другие советы
У меня первая ситуация работает нормально.В моем случае AD FS - это служба идентификации, а пользовательский STS - ресурс STS.
Все веб-приложения используют один и тот же STS ресурса, но после того, как пользователь посещает другое приложение, AD FS больше не добавляет подтвержденные утверждения, поскольку пользователь уже аутентифицирован.Как я могу принудительно выполнить или запросить основные требования из AD FS еще раз?
Я создал вызов AD FS с помощью ActAs, теперь он возвращает мои идентификационные данные.Не забудьте включить правило, разрешающее делегирование, для учетных данных, используемых для вызова AD FS.
string stsEndpoint = "https://<ADFS>/adfs/services/trust/2005/usernamemixed";
var trustChannelFactory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), stsEndpoint);
trustChannelFactory.Credentials.UserName.UserName = @"DELEGATE";
trustChannelFactory.Credentials.UserName.Password = @"PASSWORD";
trustChannelFactory.TrustVersion = TrustVersion.WSTrustFeb2005;
//// Prepare the RST.
//var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress);
var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
var rst = new RequestSecurityToken(RequestTypes.Issue);
rst.AppliesTo = new EndpointAddress(@"https:<RPADDRESS>");
// If you're doing delegation, set the ActAs value.
var principal = Thread.CurrentPrincipal as IClaimsPrincipal;
var bootstrapToken = principal.Identities[0].BootstrapToken;
// The bootstraptoken is the token received from the AD FS after succesfull authentication, this can be reused to call the AD FS the the users credentials
if (bootstrapToken == null)
{
throw new Exception("Bootstraptoken is empty, make sure SaveBootstrapTokens = true at the RP");
}
rst.ActAs = new SecurityTokenElement(bootstrapToken);
// Beware, this mode make's sure that there is no certficiate needed for the RP -> AD FS communication
rst.KeyType = KeyTypes.Bearer;
// Disable the need for AD FS to crypt the data to R-STS
Scope.SymmetricKeyEncryptionRequired = false;
// Here's where you can look up claims requirements dynamically.
rst.Claims.Add(new RequestClaim(ClaimTypes.Name));
rst.Claims.Add(new RequestClaim(ClaimTypes.PrimarySid));
// Get the token and attach it to the channel before making a request.
RequestSecurityTokenResponse rstr = null;
var issuedToken = trustChannel.Issue(rst, out rstr);
var claims = GetClaimsFromToken((GenericXmlSecurityToken)issuedToken);
private static ClaimCollection GetClaimsFromToken(GenericXmlSecurityToken genericToken)
{
var handlers = FederatedAuthentication.ServiceConfiguration.SecurityTokenHandlers;
var token = handlers.ReadToken(new XmlTextReader(new StringReader(genericToken.TokenXml.OuterXml)));
return handlers.ValidateToken(token).First().Claims;
}