Pergunta

We are attempting to use the ACS sample 4 (from http://claimsid.codeplex.com/) as template for our ADFS project. We have no problem with passive requests to ADFS authenticated services. In the sample, the federation provider is a custom STS, and the sample works fine.

Now we wish to replace the custom federation provider (Adatum FP in the sample) with our own ADFS.

Our setup right now is as follows (Namespaces hidden)

  • ServiceClient: Console Applicaton, calls Services
  • Services: WCF Webservice, Single method returning a string. This as is default [Ordertracking.Services in sample]
  • Services.Authentication: Our custom Identity Provider. This is as default [Litware.SimulatedIssuer in sample]
  • ADFS: Our Federation Provider [FederationProvider.Adatum in example]

ServiceClient wants to call Services, and from configuration it knows it has to get a token from IP (Services.Authentication). The token is then passed to ADFS, who validates the token and sends a new token back to ServiceClient. The client new passes the FP token to the service, and the service (being a relying party on ADFS) verifies the token against ADFS, and performs the service method.

The issue:

Replacing the STS in the example with ADFS, seems to break the integration. We seem to be getting the token from the IP back correctly, but we are running into problems when passing the IP token to ADFS. It seems that we have a problem with our Audience Uri's, but we have added

https://'adfs fqdn'/adfs/services/Trust/13/IssuedTokenMixedSymmetricBasic256

Client Exception We get an MessageSecurityException in the client with this InnerException InnerException {"ID3242: The security token could not be authenticated or authorized."}

[System.ServiceModel.FaultException]: {"ID3242: The security token could not be authenticated or authorized."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: null
Message: "ID3242: The security token could not be authenticated or authorized."
Source: null
StackTrace: null
TargetSite: null

ADFS Debug log

<TraceRecord xmlns="http://schemas.microsoft.com/2009/10/IdentityModel/TraceRecord" Severity="Error">
    <Description>Handled exception.</Description>
    <AppDomain>Microsoft.IdentityServer.ServiceHost.exe</AppDomain>
    <Exception>
        <ExceptionType>Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</ExceptionType>
        <Message>ID1038: The AudienceRestrictionCondition was not valid because the specified Audience is not present in AudienceUris. Audience: 'https://<adfs fqdn>/adfs/services/Trust/13/IssuedTokenMixedSymmetricBasic256'</Message>
        <StackTrace>
  at Microsoft.IdentityModel.Tokens.SamlSecurityTokenRequirement.ValidateAudienceRestriction(IList`1 allowedAudienceUris, IList`1 tokenAudiences) at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateConditions(Saml2Conditions conditions, Boolean enforceAudienceRestriction) at Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityTokenHandler.ValidateToken(SecurityToken token) at Microsoft.IdentityServer.Service.Tokens.MSISSaml2TokenHandler.ValidateToken(SecurityToken token) at Microsoft.IdentityModel.Tokens.WrappedSaml2SecurityTokenAuthenticator.ValidateTokenCore(SecurityToken token) at System.IdentityModel.Selectors.SecurityTokenAuthenticator.ValidateToken(SecurityToken token) at Microsoft.IdentityModel.Tokens.WrappedSamlSecurityTokenAuthenticator.ValidateTokenCore(SecurityToken token) at System.IdentityModel.Selectors.SecurityTokenAuthenticator.ValidateToken(SecurityToken token) at System.ServiceModel.Security.ReceiveSecurityHeader.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver, IList`1 allowedTokenAuthenticators, SecurityTokenAuthenticator&amp;amp; usedTokenAuthenticator) at
  ....
        </StackTrace>
    </Exception>
</TraceRecord>

We have added the audience uri to our IP Web.config:

<audienceUris mode="Always">
    <add value="https://<adfs fqdn>/adfs/services/Trust/13/IssuedTokenMixedSymmetricBasic256" />
</audienceUris>

If necessary we can post additional config files and screenshots of ADFS configuration.

Foi útil?

Solução

This took a bit of work but we finally solved the problem. Instead of configuring this, we built the connection in code. I'm thinking we probably had an error somewhere in the client configuration.

Some advice to anyone trying this - build the connections in code first. The XML configuration is a bit harder to work with.

We found some sample code on leastprivilege.com

private static SecurityToken GetIdPToken()
    {

        var factory = new WSTrustChannelFactory(
            new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
            "https://systemidp.dk/Issuer.svc");
        factory.TrustVersion = TrustVersion.WSTrust13;

        factory.Credentials.UserName.UserName = "LITWARE\\rick";
        factory.Credentials.UserName.Password = "thisPasswordIsNotChecked";

        var rst = new RequestSecurityToken
        {
            RequestType = WSTrust13Constants.RequestTypes.Issue,
            AppliesTo = new EndpointAddress("https://adfsfqdn/adfs/services/trust"),
            KeyType = WSTrust13Constants.KeyTypes.Symmetric,
            ReplyTo = "https://adfsfqdn/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256/"
        };
        factory.ConfigureChannelFactory();
        var channel = factory.CreateChannel();
        return channel.Issue(rst);
    }

    private static SecurityToken GetRSTSToken(SecurityToken idpToken)
    {
        var binding = new IssuedTokenWSTrustBinding();
        binding.SecurityMode = SecurityMode.TransportWithMessageCredential;

        var factory = new WSTrustChannelFactory(
            binding,
            "https://adfsfqdn/adfs/services/trust/13/issuedtokenmixedsymmetricbasic256/");
        factory.TrustVersion = TrustVersion.WSTrust13;
        factory.Credentials.SupportInteractive = false;

        var rst = new RequestSecurityToken
        {
            RequestType = WSTrust13Constants.RequestTypes.Issue,
            AppliesTo = new EndpointAddress("https://services.dk/WebService.svc"),
            KeyType = WSTrust13Constants.KeyTypes.Symmetric
        };

        factory.ConfigureChannelFactory();
        var channel = factory.CreateChannelWithIssuedToken(idpToken);
        return channel.Issue(rst);
    }

Creating a WCF call with the token

var ipdtoken = GetIdPToken();
var stsToken = GetRSTSToken(ipdtoken);
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.EstablishSecurityContext = false;
var factory = new ChannelFactory<IWebService>(binding, "https://services.dk/WebService.svc");

factory.ConfigureChannelFactory();
factory.Credentials.SupportInteractive = false;

var serviceChannel = factory.CreateChannelWithIssuedToken(stsToken);

var s = serviceChannel.GetUserInformation();

Outras dicas

The audienceUri configuration on your IP looks fine. I think ADFS is the one that's throwing the ID3242 fault. Can you check to make sure your IP is correctly configured under Claim Provider Trusts on your ADFS server?

If you have your IP's federation metadata handy, you could also try recreating it in ADFS.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top