Geminimale

Hi,

Forgive me if this has already been answered. I have an STS/IP service that issues SAML tokens to a client which would be forwarded to a service when it is required. Okay, standard types of WS-Federation stuff. In my situation we have multiple services in the same security realm. Now to the question, when the client presents the SAML token to the service I do want to check the claims, credentials, setup the IPrincipal, etc. That is no problem, but I would also like to retrieve access to the SAML token directly so that it could be passed off to other services in my organization. I know, I could build another token and pass that along but that seems like overkill, the client has provided a SAML token that I should be able to pass along to another service on behalf of the client. What I am having a problem with is determining how I should go about getting access to the SAML token. Any help would be greatly appreciated.

Thanks



Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Brent Schmaltz - MSFT

This piece of code will fish the saml token out of the message, assume this class has a member data of samltoken.

protected override SecurityToken GetTokenCore(TimeSpan timeout)

{

if (this.samlSecurityToken == null)

{

lock (this.samlSecurityTokenLock)

if (this.samlSecurityToken == null)

{

SecurityMessageProperty securityMessageProperty = OperationContext.Current.RequestContext.RequestMessage.Properties.Security;

// if protection token is not found or not a SamlSecurityToken, look in supporting tokens.

if (securityMessageProperty.ProtectionToken == null || (!(securityMessageProperty.ProtectionToken.SecurityToken is SamlSecurityToken)))

{

SecurityMessageProperty smp = OperationContext.Current.RequestContext.RequestMessage.Properties.Security;

if (securityMessageProperty.HasIncomingSupportingTokens)

{

foreach (SupportingTokenSpecification supportingToken in OperationContext.Current.RequestContext.RequestMessage.Properties.Security.IncomingSupportingTokens)

{

if (supportingToken.SecurityToken is SamlSecurityToken)

{

this.samlSecurityToken = supportingToken.SecurityToken as SamlSecurityToken;

break;

}

}

}

}

else

this.samlSecurityToken = securityMessageProperty.ProtectionToken.SecurityToken as SamlSecurityToken;

}

if (this.samlSecurityToken == null)

throw new Exception("Expecting a valid SAML token as Protection or Supporting token.");

}

return this.samlSecurityToken;





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Geminimale

Hi Brent,

Thanks a lot for the example code. In looking at the code, I treated the request to the next server as a client. E.G. The client passed a SAML token to my service, my service then acts as the client in the next call so I added the TokenManager, TokenProvider, etc and associated it with my service. I hit the breakpoint I set for the GetTokenCore but I find the HasIncomingSupportingTokens is false, yet I see that ServiceSecurityContext.AuthorizationContext contains the Claims that were sent from the STS service. I am unable to really find anything that explains how the HasIncomingSupportingTokens is created. Is it something special I need to do at the STS Service, ServerAuthorizationManager Also, if I wished to get access to the token during or prior to ServiceAuthorization is that possible

Thanks,

Dan





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Brent Schmaltz - MSFT

What does your binding look like

If you are using the SamlToken as a proof token the it is the ProtectionToken that will be your SamlToken.





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Geminimale

Hi Brent,

This is probably more than you were asking for but following is the saml token message that is presented to the Server by the client. Following that I have included the Servers and Clients Bindings. I did not include the STS Server as it is just your standard wsHttpBinding. I will look into how to create the SamlToken as a ProtectionToken. Again, thanks for the help.

Dan

<s:Envelope xmlnsTongue Tied="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

<s:Header>

<a:Action s:mustUnderstand="1" u:Id="_5">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>

<a:MessageID u:Id="_6">urn:uuid:ab44af19-7db7-4865-99ac-4eb07947bddb</a:MessageID>

<a:ReplyTo u:Id="_7">

<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>

</a:ReplyTo>

<a:To s:mustUnderstand="1" u:Id="_8">http://devaa2986:8008/AdvantageIQ.AIQService/AIQFunctions</a:To>

<oTongue Tiedecurity s:mustUnderstand="1" xmlnsSurprise="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<u:Timestamp u:Id="uuid-8a5e9e48-b132-4baa-95d5-a4027123e94d-15">

<u:Created>2007-10-26T15:00:41.718Z</u:Created>

<u:Expires>2007-10-26T15:05:41.718Z</u:Expires>

</u:Timestamp>

<cTongue TiedecurityContextToken u:Id="uuid-2402d297-6b82-4d37-8d38-82702cd42a83-1" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">

<c:Identifier>urn:uuid:af0e8470-3439-433c-8288-1423a0b19bc0</c:Identifier>

<dnse:Cookie xmlnsBig Smilense="http://schemas.microsoft.com/ws/2006/05/security"><!-- Removed --></dnse:Cookie>

</cTongue TiedecurityContextToken>

<cBig SmileerivedKeyToken u:Id="_0" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">

<oTongue TiedecurityTokenReference>

<o:Reference ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" URI="#uuid-2402d297-6b82-4d37-8d38-82702cd42a83-1"/>

</oTongue TiedecurityTokenReference>

<cSurpriseffset>0</cSurpriseffset>

<c:Length>24</c:Length>

<c:Nonce>

<!-- Removed -->

</c:Nonce>

</cBig SmileerivedKeyToken>

<cBig SmileerivedKeyToken u:Id="_2" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">

<oTongue TiedecurityTokenReference>

<o:Reference ValueType="http://schemas.xmlsoap.org/ws/2005/02/sc/sct" URI="#uuid-2402d297-6b82-4d37-8d38-82702cd42a83-1"/>

</oTongue TiedecurityTokenReference>

<c:Nonce>

<!-- Removed -->

</c:Nonce>

</cBig SmileerivedKeyToken>

<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<eBig SmileataReference URI="#_4"/>

<eBig SmileataReference URI="#_10"/>

<eBig SmileataReference URI="#_11"/>

</e:ReferenceList>

<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_c004784e-46dd-4f4f-89a0-b86e4728dd0c" Issuer="AIQ STS Service" IssueInstant="2007-10-26T15:00:41.671Z" xmlnsTongue Tiedaml="urnSurpriseasis:names:tcTongue TiedAML:1.0:assertion">

<saml:Conditions NotBefore="2007-10-26T14:55:41.640Z" NotOnOrAfter="2007-10-27T01:00:41.640Z"/>

<saml:Advice/>

<saml:AttributeStatement>

<samlTongue Tiedubject>

<samlTongue TiedubjectConfirmation>

<saml:ConfirmationMethod>urnSurpriseasis:names:tcTongue TiedAML:1.0:cm:holder-of-key</saml:ConfirmationMethod>

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">

<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

</e:EncryptionMethod>

<KeyInfo>

<oTongue TiedecurityTokenReference>

<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">t36phKNBled6fY4Ud8KAo+2tuvk=</o:KeyIdentifier>

</oTongue TiedecurityTokenReference>

</KeyInfo>

<e:CipherData>

<e:CipherValue><!-- Removed --></e:CipherValue>

</e:CipherData>

</e:EncryptedKey>

</KeyInfo>

</samlTongue TiedubjectConfirmation>

</samlTongue Tiedubject>

<saml:Attribute AttributeName="name" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">

<saml:AttributeValue>

<!-- Removed -->

</saml:AttributeValue>

</saml:Attribute>

<saml:Attribute AttributeName="spn" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">

<saml:AttributeValue>

<!-- Removed -->

</saml:AttributeValue>

</saml:Attribute>

<saml:Attribute AttributeName="upn" AttributeNamespace="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">

<saml:AttributeValue>

<!-- Removed -->

</saml:AttributeValue>

</saml:Attribute>

<saml:Attribute AttributeName="accessAuthorized" AttributeNamespace="http://AdvantageIQ.com">

<saml:AttributeValue>

<!-- Removed -->

</saml:AttributeValue>

</saml:Attribute>

</saml:AttributeStatement>

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">

<SignedInfo>

<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>

<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>

<Reference URI="#_c004784e-46dd-4f4f-89a0-b86e4728dd0c">

<Transforms>

<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>

<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>

</Transforms>

<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>

<DigestValue>AD8/SddRMMhW0w54mvj2kmT2tgo=</DigestValue>

</Reference>

</SignedInfo>

<SignatureValue><!-- Removed --></SignatureValue>

<KeyInfo>

<oTongue TiedecurityTokenReference>

<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">t36phKNBled6fY4Ud8KAo+2tuvk=</o:KeyIdentifier>

</oTongue TiedecurityTokenReference>

</KeyInfo>

</Signature>

</saml:Assertion>

<cBig SmileerivedKeyToken u:Id="_9" xmlns:c="http://schemas.xmlsoap.org/ws/2005/02/sc">

<oTongue TiedecurityTokenReference>

<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">_c004784e-46dd-4f4f-89a0-b86e4728dd0c</o:KeyIdentifier>

</oTongue TiedecurityTokenReference>

<cSurpriseffset>0</cSurpriseffset>

<c:Length>24</c:Length>

<c:Nonce>

<!-- Removed -->

</c:Nonce>

</cBig SmileerivedKeyToken>

<e:EncryptedData Id="_10" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<oTongue TiedecurityTokenReference>

<o:Reference URI="#_2"/>

</oTongue TiedecurityTokenReference>

</KeyInfo>

<e:CipherData>

<e:CipherValue><!-- Removed --></e:CipherValue>

</e:CipherData>

</e:EncryptedData>

<e:EncryptedData Id="_11" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<oTongue TiedecurityTokenReference>

<o:Reference URI="#_2"/>

</oTongue TiedecurityTokenReference>

</KeyInfo>

<e:CipherData>

<e:CipherValue><!-- Removed --></e:CipherValue>

</e:CipherData>

</e:EncryptedData>

</oTongue Tiedecurity>

</s:Header>

<s:Body u:Id="_3">

<e:EncryptedData Id="_4" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">

<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>

<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">

<oTongue TiedecurityTokenReference xmlnsSurprise="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

<o:Reference URI="#_2"/>

</oTongue TiedecurityTokenReference>

</KeyInfo>

<e:CipherData>

<e:CipherValue><!-- Removed --></e:CipherValue>

</e:CipherData>

</e:EncryptedData>

</s:Body>

</s:Envelope>

------------------------------------------------------ Servers Binding -----------------------------------

< xml version="1.0" encoding="utf-8" >
<configuration>
<system.serviceModel>

<services>
<service behaviorConfiguration="AIQService"
name="AdvantageIQ.STS.AIQServiceFunctions">

<endpoint address="AIQFunctions"
binding="wsFederationHttpBinding"
bindingConfiguration="AIQStsExample"
name="AIQFunctions"
contract="AdvantageIQ.STS.IAIQServiceFunctions" />

<endpoint address="metaData"
binding="mexHttpBinding"
name="MetaDataExchange"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://DEVAA2986:8008/AdvantageIQ.AIQService" />
</baseAddresses>
</host>
</service>
</services>

<client>
<endpoint address="http://DEVAA2986:8012/AdvantageIQ.AIQVendor/AIQVendorFunctions"
binding="wsFederationHttpBinding"
bindingConfiguration="AIQFunctions"
contract="AdvantageIQ.STS.VendorService.AIQServiceFunctions"
name="AIQVendor"
behaviorConfiguration="clientCert">
<identity>
<dns value="AIQStsService.com"/>
</identity>
</endpoint>
</client>

<bindings>
<wsFederationHttpBinding>
<binding name="AIQStsExample" openTimeout="00:02:00">
<security mode="Message">
<message issuedKeyType="AsymmetricKey"
issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">

<!--<claimTypeRequirements>
<add claimType="http://AdvantageIQ.com:accessAuthorized" />
</claimTypeRequirements>-->

<issuer address="http://localhost:8006/AdvantageIQ.STSService/UserNameAuthorization" />
<issuerMetadata address="http://localhost:8006/AdvantageIQ.STSService/metaData" >
</issuerMetadata>
</message>
</security>
</binding>

<binding name="AIQFunctions">
<security mode="Message">
<message>
<issuer address="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization"
binding="wsHttpBinding"
bindingConfiguration="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization">
<identity>
<dns value="AIQStsService.com"/>
</identity>
</issuer>
</message>
</security>
</binding>

</wsFederationHttpBinding>

<wsHttpBinding>
<binding name="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>

</bindings>

<behaviors>
<endpointBehaviors>
<behavior name="clientCert">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="AIQService">
<serviceAuthorization serviceAuthorizationManagerType="AdvantageIQ.STS.ServiceAuthorization, AdvantageIQ.STS.AIQService" />
<serviceCredentials>
<serviceCertificate findValue="AIQStsService.com"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>

</serviceCredentials>
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>



</system.serviceModel>

</configuration>

------------------------------------------ Client Binding ------------------------------------

< xml version="1.0" encoding="utf-8" >
<configuration>
<system.serviceModel>
<bindings>
<wsFederationHttpBinding>
<binding name="AIQFunctions">
<security mode="Message">
<message>
<issuer address="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization"
binding="wsHttpBinding"
bindingConfiguration="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization">
<identity>
<dns value="AIQStsService.com"/>
</identity>
</issuer>
</message>
</security>
</binding>

</wsFederationHttpBinding>

<wsHttpBinding>
<binding name="http://DEVAA2986:8006/AdvantageIQ.STSService/UserNameAuthorization">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://DEVAA2986:8008/AdvantageIQ.AIQService/AIQFunctions"
binding="wsFederationHttpBinding"
bindingConfiguration="AIQFunctions"
contract="AdvantageIQ.STS.AIQServiceFunctions.AIQServiceFunctions"
name="AIQFunctions"
behaviorConfiguration="clientCert">
<identity>
<dns value="HomeRealmSTS.com"/>
</identity>
</endpoint>
<endpoint address="http://DEVAA2986:8012/AdvantageIQ.AIQVendor/AIQVendorFunctions"
binding="wsFederationHttpBinding"
bindingConfiguration="AIQFunctions"
contract="AdvantageIQ.STS.VendorService.AIQServiceFunctions"
name="AIQVendor"
behaviorConfiguration="clientCert">
<identity>
<dns value="AIQStsService.com"/>
</identity>
</endpoint>
</client>

<behaviors>
<endpointBehaviors>
<behavior name="clientCert">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>

</system.serviceModel>

</configuration>





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Geminimale

Hi All,

Still not having very much luck with getting the Saml Token at the Server. I know it is getting there, I did write a SamlSerializer to try and access the token and was successful but it is slow since I would have to send the Saml token with every message and does not really help when I am working with large numbers of client. I still have not figured out what I am doing wrong in my Saml Token such that it is not being sent as Supporting Token at the server. It looks like the token is only on the SCT message and not the remaining messages when the service is being accessed multiple times. So, looking for suggestions of how I can get the Saml Token so that I can forward it as a message to another service. Guess I am surprised that it is so hard to just get a token that should be easy to find. As always, any help would be appreciated.





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Todd West - MSFT

You can't get at the SAML token from your service code because the binding's using secure conversation, which sucks up the SAML token and converts it to an SCT. Look here to see how to turn of the secure session created by use of secure conversation. You might also check out the SAML forwarding sample.





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Geminimale

Hi Todd,

Thanks for the input. I will look at the information and determine how we want to go forward with this.

Dan





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

J F Karp

I'm having the same issue as the original post (I am using the old STS Quick Start code, but the problem is the same). Is there no way to remember the SAMl token on the server side from the SCT call With SessionState, OperationState, and a seemingly endless supply of Soap Contexts, I'm surprised there isn't a place to store the SAML token for later use after the secure conversation is established. Does starting the secure conversation change the "session" between the client and the server

Thanks for any input...
-jk




Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Brent Schmaltz - MSFT

You can catch the token by adding a SecurityTokenAuthenticator that derives from the SamlSecurityTokenAuthenticator and handles the saml token and just wraps it and does one special thing. Wrap the IAuthorizationPolicies that are returned by ValidateToken and when Evaluate is called have the base do it's thing and add one special claim that is the SamlToken.

This is totaly doable as I have used such a procedure, however I am being brief and assuming you know how to hook into the runtime. Let me know if you need pointing to samples.





Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

J F Karp

Is the solution you suggest specific to .NET 3.0 and higher At the moment, i am tied to .NET 2.0 and WSE 3.0 (and VS 2005). But, I'll take any pointers or elaborations you can provide Smile.

Thanks,
-jk




Re: Windows Communication Foundation (Indigo) Access SAML Tokens at the Server

Brent Schmaltz - MSFT

Yes it is specific to .Net 3.0. You will need to be comfortable with SecurityToken extensions in WCF.