Как преобразовать строку токена XML SAML в экземпляр SecurityToken или ClaimsPrincipal?
Мой контекст:
- .Net веб-сервис RESTful
- Клиент (смешанные платформы, технологии, возможности lib) получил маркер SAML
- Попытка принять токен для аутентификации/авторизации в службе REST
- в HTTP-авторизации/заголовок X-Authorization
- в качестве параметра запроса
- Будет также поддерживаться SWT позже, но нужно получить токены SAML
Подробнее:
У меня есть токен SAML в строке:
<saml:Assertion xmlns:saml="..." ...> ..etc... </>
В HttpModule я хочу преобразовать это в ClaimsPrincipal, чтобы моя служба могла выполнять обычный Thread.CurrentPrincipal как материал IClaimsPrincipal.
Я нашел пару соблазняющих страниц/блогов и т.д., которые выглядели полезными:
Я застрял буквально, пытаясь превратить маркер SAML в ClaimsPrincipal (через промежуточный шаг SecurityToken или прямой... счастливый в любом случае). Пример кода из идеи Cibrax использует для критического этапа проверки и десериализации следующее:
SecurityTokenSerializer securityTokenSerializer
= new SecurityTokenSerializerAdapter(
FederatedAuthentication.SecurityTokenHandlers,
MessageSecurityVersion.Default.SecurityVersion,
false, new SamlSerializer(), null, null);
SecurityToken theToken
= WSFederationAuthenticationModule.GetSecurityToken(
theSamlTokenInStringForm, securityTokenSerializer);
Стена, на которой я попал, - это то, что версия WIM RTM не подвергает этой перегрузке GetSecurityToken... она раскрывает только:
WSFederationAuthenticationModule fam = new WSFederationAuthenticationModule();
SecurityToken theToken = fam.GetSecurityToken(HttpRequest theRequest);
SecurityToken theToken = fam.GetSecurityToken(SignInResponseMessage message);
Спасибо, что помогли мне расклеиться!
Тайлер
Ответы
Ответ 1
Просто нашел это полезным.
http://www.tecsupra.com/blog/system-identitymodel-manually-parsing-the-saml-token/
Основная идея: вам нужен XML "Аудитория" - node, а затем вы можете использовать SecurityTokenHandlerCollection и использовать "ValidateToken"
Из сообщения:
string samlTokenXml = signInResponseXml
.DocumentElement // <trust:RequestSecurityTokenResponseCollection>
.ChildNodes[0] // <trust:RequestSecurityTokenResponse>
.ChildNodes[2] // <trust:RequestedSecurityToken>
.InnerXml; // <Assertion>
var xmlTextReader = new XmlTextReader(new StringReader(samlTokenXml));
SecurityTokenHandlerCollection handlers =
FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers;
// read the token
SecurityToken securityToken = handlers.ReadToken(xmlTextReader);
Ответ 2
Я хочу поделиться некоторыми ресурсами, которые я нашел очень полезными при реализации по существу одного и того же сценария. В принципе, Доминик Байер является богом в этом пространстве. Его блог полон замечательной информации по теме:
http://leastprivilege.com/
Для преобразования маркера SAML/SWT в IClaimsIdentity в службе RESTful:
http://www.develop.com/wcfrest/
http://identitymodel.codeplex.com/
Ответ 3
Хорошо, некоторый прогресс... если я сделаю следующее, я получу дальше:
Microsoft.IdentityModel.Configuration.ServiceConfiguration serviceConfig
= new Microsoft.IdentityModel.Configuration.ServiceConfiguration();
// Now read the token and convert it to an IPrincipal
SecurityToken theToken = null;
ClaimsIdentityCollection claimsIdentity = null;
using (XmlReader reader = XmlReader.Create(new StringReader(authSamlString)))
{
theToken = serviceConfig.SecurityTokenHandlers.ReadToken(reader);
claimsIdentity = serviceConfig.SecurityTokenHandlers.ValidateToken(theToken);
}
IPrincipal principal = new ClaimsPrincipal(claimsIdentity);
Следующая стена, на которой я ударил:
Теперь я получаю исключение в распределении хоста службы REST, созданного мастером:
<%@ ServiceHost Language="C#" Debug="true" Service="Sample.RestService.Service" Factory="Sample.RestService.AppServiceHostFactory"%>
using System;
using System.ServiceModel;
using System.ServiceModel.Activation;
using Microsoft.ServiceModel.Web.SpecializedServices;
namespace Sample.RestService
{
class AppServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
/// ***** The exception occurs on the next line *****
return new SingletonServiceHost(serviceType, baseAddresses);
}
}
}
Сведения об исключении:
System.Configuration.ConfigurationErrorsException occurred
Message="This element is not currently associated with any context"
Source="System.Configuration"
BareMessage="This element is not currently associated with any context"
Line=0
StackTrace:
at System.Configuration.ConfigurationElement.get_EvaluationContext()
InnerException: {{NONE}}
Ответ 4
Для устранения последнего исключения проверьте тег и его содержимое и убедитесь, что оно правильно. Я не могу сказать, какой элемент имеет проблему. Мы повторяем эту ошибку несколько раз, и каждый раз причина была неправильной.