I’m having an issue using ADFS2 to secure a back-end WCF service that is being called from Passively Federated Website. I have the passive federation working on the website, but the back-end service is giving me problems.
The pieces of the puzzle.
- Silverlight Client that is being served from Passively Federated Website.
- The Silverlight calls a WCF service (App Service), hosted on the passively Federated Website.
- I have SaveBootstrapToken set to true in the config.
- From the App Service, I want to call a back-end WCF service using BootstrapToken with the ActAs scenarion.
- Federated Website and Back-end WCF service are setup as separate RPs in the ADFS2, token encryption is turned on. Both are allowed to delegate.
Back-end Service configuration:
I have WIF incorporated into the pipeline using behavior extension.
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IQuoteService">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
</issuer>
<issuerMetadata address="https://myADFSserver/adfs/services/trust/mex">
</issuerMetadata>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<behaviors>
<serviceBehaviors>
<behavior name="">
<federatedServiceHostConfiguration name="Service.QuoteService" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate findValue="000000000000000000000000000000" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service.QuoteService">
<endpoint address="" binding="ws2007FederationHttpBinding" contract="Service.IQuoteService" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Client Configuration
When add the service using Add Service Reference tooling, the following config on the client gets created:
<customBinding>
<binding name="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256">
<security defaultAlgorithmSuite="Default" authenticationMode="IssuedTokenOverTransport"
requireDerivedKeys="false" securityHeaderLayout="Strict" includeTimestamp="true"
keyEntropyMode="CombinedEntropy" messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
<issuedTokenParameters keySize="256" keyType="SymmetricKey" tokenType="">
<additionalRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
<trust:KeySize>256</trust:KeySize>
<trust:KeyWrapAlgorithm>http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
<trust:EncryptWith>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
<trust:SignatureAlgorithm>http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignatureAlgorithm>
<trust:CanonicalizationAlgorithm>http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm>http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</additionalRequestParameters>
</issuedTokenParameters>
<localClientSettings cacheCookies="true" detectReplays="false"
replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
<localServiceSettings detectReplays="false" issuedCookieLifetime="10:00:00"
maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
reconnectTransportOnFailure="true" maxPendingSessions="128"
maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
<secureConversationBootstrap />
</security>
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Default" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" requireClientCertificate="false" />
</binding>
</customBinding>
<ws2007FederationHttpBinding>
<binding name="WS2007FederationHttpBinding_IQuoteService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<message algorithmSuite="Default" issuedKeyType="SymmetricKey"
negotiateServiceCredential="true">
<issuer address="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256"
binding="customBinding" bindingConfiguration="https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256" />
<issuerMetadata address="https://myADFSserver/adfs/services/trust/mex" />
<tokenRequestParameters>
<trust:SecondaryParameters xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<trust:KeyType xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>
<trust:KeySize xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">256</trust:KeySize>
<trust:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity"
xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsid:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
<wsid:ClaimType Uri="http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
Optional="true" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity" />
</trust:Claims>
<trust:KeyWrapAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p</trust:KeyWrapAlgorithm>
<trust:EncryptWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptWith>
<trust:SignWith xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2000/09/xmldsig#hmac-sha1</trust:SignWith>
<trust:CanonicalizationAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/10/xml-exc-c14n#</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">http://www.w3.org/2001/04/xmlenc#aes256-cbc</trust:EncryptionAlgorithm>
</trust:SecondaryParameters>
</tokenRequestParameters>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
<client>
<endpoint address="http://myServiceHost/Service/QuoteService.svc"
binding="ws2007FederationHttpBinding" bindingConfiguration="WS2007FederationHttpBinding_IQuoteService"
contract="QuoteService.IQuoteService" name="WS2007FederationHttpBinding_IQuoteService">
<identity>
<certificate encodedValue="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
</identity>
</endpoint>
</client>
Here's the Service Client Code:
List<Quote> quoteList = new List<Quote>();
ClaimsPrincipal myClaimsPrincipal = System.Web.HttpContext.Current.User as ClaimsPrincipal;
SecurityToken bootstrapToken = myClaimsPrincipal.Identities[0].BootstrapToken;
if (bootstrapToken == null)
{
throw new Exception("bootstrap tokein is null. Logout and try again.");
}
ChannelFactory<IQuoteServiceChannel> factory = new ChannelFactory<IQuoteServiceChannel>("WS2007FederationHttpBinding_IQuoteService");
factory.Credentials.SupportInteractive = false;
factory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "0000000000000000000000000000");
factory.ConfigureChannelFactory();
IQuoteServiceChannel channel;
//Create the channel with the bootstrap token
channel = factory.CreateChannelActingAs(bootstrapToken);
try
{
quoteList = channel.GetQuotes(quoteUser);
channel.Close();
}
catch (SecurityAccessDeniedException sadex)
{
channel.Abort();
throw;
}
catch (CommunicationException exception)
{
channel.Abort();
throw;
}
catch (TimeoutException timeoutEx)
{
channel.Abort();
throw;
}
catch (Exception ex)
{
channel.Abort();
throw;
}
return quoteList;
This is the exception I get:
System.ServiceModel.Security.SecurityNegotiationException was unhandled by user code
Message=SOAP security negotiation with 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' failed. See inner exception for more details.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at Microsoft.IdentityModel.Protocols.WSTrust.FederatedSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecurityProtocol.TryGetSupportingTokens(SecurityProtocolFactory factory, EndpointAddress target, Uri via, Message message, TimeSpan timeout, Boolean isBlockingCall, IList`1& supportingTokens)
at System.ServiceModel.Security.SymmetricSecurityProtocol.TryGetTokenSynchronouslyForOutgoingSecurity(Message message, SecurityProtocolCorrelationState correlationState, Boolean isBlockingCall, TimeSpan timeout, SecurityToken& token, SecurityTokenParameters& tokenParameters, SecurityToken& prerequisiteWrappingToken, IList`1& supportingTokens, SecurityProtocolCorrelationState& newCorrelationState)
at System.ServiceModel.Security.SymmetricSecurityProtocol.SecureOutgoingMessageCore(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
at System.ServiceModel.Security.MessageSecurityProtocol.SecureOutgoingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState correlationState)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at OMG.Admin.DemoApp.Business.QuoteService.IQuoteService.GetQuotes(User quoteUser)
at OMG.Admin.DemoApp.Business.QuoteServiceClient.GetQuotes(User quoteUser) in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteServiceClient.cs:line 131
at OMG.Admin.DemoApp.Business.QuoteBO.GetQuoteList() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Business\QuoteBO.cs:line 26
at OMG.Admin.DemoApp.Web.Services.DemoAppService.GetQuotes() in C:\OMG_TFS01\OMG.Admin\OMG.Admin.DemoApp\OMG.Admin.DemoApp.Web\Services\DemoAppService.svc.cs:line 27
at SyncInvokeGetQuotes(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
InnerException: System.InvalidOperationException
Message=The address of the security token issuer is not specified. An explicit issuer address must be specified in the binding for target 'https://myADFSserver/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256' or the local issuer address must be configured in the credentials.
Source=mscorlib
StackTrace:
Server stack trace:
at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateIssuedSecurityTokenProvider(InitiatorServiceModelSecurityTokenRequirement initiatorRequirement)
at System.ServiceModel.ClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement, Boolean disableInfoCard)
at Microsoft.IdentityModel.Protocols.WSTrust.FederatedClientCredentialsSecurityTokenManager.CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement)
at System.ServiceModel.Security.SecurityProtocol.AddSupportingTokenProviders(SupportingTokenParameters supportingTokenParameters, Boolean isOptional, IList`1 providerSpecList)
at System.ServiceModel.Security.SecurityProtocol.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
InnerException:
I'm sure I'm missing something in the configuration and/or code can someone help me out?
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
does that mean that I can't use the bootstrap token to authenticate? Because it's not symmetric key but a bearer key? – Eugene S.