Query WS-Trust 1.4 STS con .NET / WIF / WCF
Pregunta
Necesito consultar un servicio de WS Trust 1.4 usando .NET para habilitar un escenario de autenticación SAML 2.0.
Editar: Para ser más precisos, necesito admitir un desafío de interacción de usuario en el lado del cliente que se define en WS Trust 1.4.
Miré en WiF, lo que brinda acceso directo a WS Confianza a través de WSTUSTChannelfactactory (consulte TrustChannelfactory.trustversion en el códigos de códigos ...) ¡Pero parece que solo hay soporte para WS-Trust 1.3 y FEB2005?
WSTrustChannelFactory trustChannelFactory = new WSTrustChannelFactory(getBinding(), "http:/localhost...");
trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;
WSTrustChannel channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
RequestSecurityToken rst = new RequestSecurityToken();
RequestSecurityTokenResponse rstr = null;
SecurityToken token = channel.Issue(rst, out rstr);
¿Alguien sabe cómo implementar una consulta WS-Fust-Fusting directa usando .NET?
No puedo usar una vinculación de WSHTTPFEEDERACIÓN ya que necesitamos trabajar con SAML 2.0 y debemos recuperar las solicitudes de autenticación SAML 2.0 del servidor de aplicaciones antes de pasarlas a IDP.
Por supuesto, podría rodar mi propio lado de cliente WS-Trust 1.4.Implementación, pero quizás haya una manera más fácil ...
Solución
Extendé la implementación de confianza WIF WS usando métodos de extensión .NET.Aquí puede ver la primera parte (solicitud de emisión con la solicitud de RST y SAML AUTHN) como ejemplo sobre cómo reutilizar las cosas que ya están definidas en WiF.Utilicé un desasmador de IL para ver cómo se hacen las cosas dentro de WiF que fue bastante útil en el camino ...
internal static RequestSecurityTokenResponseWithSAML2Assertion Issue(this WSTrustChannel pThis,
string pSAML2AuthnRequest,
Func<ProfileSelectionChallengeType, wsTrust14.ChoiceSelectedType> pProfileSelectionCallback)
{
if (pThis != null)
{
if (pThis.ChannelFactory != null &&
pThis.ChannelFactory.Endpoint != null &&
pThis.ChannelFactory.Endpoint.Binding != null)
{
// Create RST Request
RequestSecurityToken rst = new RequestSecurityToken("http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue");
rst.TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0";
// we use WS Trust 1.4 but .NET WIF only provides support for WS Trust 1.3
// so we add the needed Challenge support and reuse most of the WIF stuff
if (pThis.TrustVersion != System.ServiceModel.Security.TrustVersion.WSTrust13)
{
throw new Exception("Given WS Trust Version not supported!");
}
// create a WS Trust 1.3 SOAP Message
Message issueRequest = Message.CreateMessage(pThis.ChannelFactory.Endpoint.Binding.MessageVersion,
"http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue",
new WSTrustRequestBodyWriter(rst,
pThis.WSTrustRequestSerializer,
pThis.WSTrustSerializationContext));
// add SAML Authn Request to the WS Trust request
XmlDocument messageAsXml = issueRequest.serializeToXml();
messageAsXml = SAMLSupport.addSAMLAuthenticationRequest(messageAsXml, pSAML2AuthnRequest);
issueRequest = issueRequest.generateFromXml(messageAsXml);
// invoke the WS Trust service on the STS
Message responseMessage = pThis.Issue(issueRequest);
// check what we received as answer...
var response = pThis.parseAndHandleResponse(responseMessage, pProfileSelectionCallback);
return response;
}
}