使用和ADFS实现ACS作为STS

时间:2011-10-19 09:52:40

标签: c# .net wcf adfs acs

我们正在尝试使用ACS示例4(来自http://claimsid.codeplex.com/)作为ADFS项目的模板。 对ADFS身份验证服务的被动请求没有问题。在示例中,联合提供程序是自定义STS,并且示例工作正常。

现在我们希望用自己的ADFS替换自定义联合提供程序(示例中的Adatum FP)。

我们现在的设置如下(名称空间隐藏)

  • ServiceClient:Console Applicaton,调用服务
  • 服务:WCF Webservice,返回字符串的Single方法。这是默认值 [Ordertracking.Services in sample]
  • Services.Authentication:我们的自定义身份提供商。这是默认[样本中的Litware.SimulatedIssuer]
  • ADFS:我们的联邦提供商[FederationProvider.Adatum in 示例]

ServiceClient想要调用服务,并且从配置中知道它必须从IP(Services.Authentication)获取令牌。然后将令牌传递给ADFS,ADFS验证令牌 并将新令牌发送回ServiceClient。客户端new将FP令牌传递给服务,服务(作为ADFS上的依赖方)根据ADFS验证令牌,并执行服务方法。

问题:

用ADFS替换示例中的STS似乎打破了集成。我们似乎正在从IP中正确获取令牌,但是在将IP令牌传递给ADFS时遇到了问题。 我们的Audience Uri似乎有问题,但我们已添加

  

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

客户端例外 我们在客户端中使用此InnerException获取MessageSecurityException 的InnerException     {“ID3242:无法对安全令牌进行身份验证或授权。”}

[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调试日志

<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>

我们已将观众uri添加到我们的IP Web.config:

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

如有必要,我们可以发布ADFS配置的其他配置文件和屏幕截图。

2 个答案:

答案 0 :(得分:5)

这需要一些工作,但我们终于解决了这个问题。我们不是配置它,而是在代码中构建连接。我想我们可能在客户端配置中的某个地方出现了错误。

对尝试此操作的任何人提出一些建议 - 首先在代码中构建连接。 XML配置有点难以使用。

我们在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);
    }

使用令牌

创建WCF调用
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();

答案 1 :(得分:0)

您的IP上的audienceUri配置看起来很好。我认为ADFS是一个抛出ID3242错误的人。您是否可以检查以确保在ADFS服务器上的Claim Provider Trusts下正确配置了IP?

如果您的IP联合元数据很方便,您也可以尝试在ADFS中重新创建它。