在不使用WIF的情况下在WCF服务调用中包含SAML2.0令牌

Wou*_*oos 14 c# wcf adfs saml-2.0 .net-4.5

我正在尝试设置WCF受保护的服务ADFS.我目前能够请求令牌,并使用请求发送WIF,并Thinktecture IdentityModel 4.5用下面的代码:

static SecurityToken GetToken()
{
    var factory = new WSTrustChannelFactory(
          new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
          "https://fs2.server2012.local/adfs/services/trust/13/usernamemixed") 
    {
        TrustVersion = TrustVersion.WSTrust13 
    };


    if (factory.Credentials != null)
    {
        factory.Credentials.UserName.UserName = @"username";
        factory.Credentials.UserName.Password = "password";
    }

    var rst = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        KeyType = KeyTypes.Symmetric,
        AppliesTo = new EndpointReference(
            "https://wcfservicecertificate/wcfservice/Service.svc/wstrust"),
    };

    var channel = factory.CreateChannel();
    RequestSecurityTokenResponse rstr;
    return channel.Issue(rst, out rstr);
}
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以使用以下方法调用WCF服务ChannelFactory.CreateChannelWithIssuedToken:

var factory = new ChannelFactory<IService>(binding, 
    new EndpointAddress("https://wcfservicecertificate/wcfservice/Service.svc/wstrust"));
if (factory.Credentials != null)
{
    factory.Credentials.SupportInteractive = false;
    factory.Credentials.UseIdentityConfiguration = true;
}

var proxy = factory.CreateChannelWithIssuedToken(GetToken());
var result= proxy.GetData(2);
Run Code Online (Sandbox Code Playgroud)

这按预期工作,但只能在(移动)Windows平台上使用.我也希望能够在iOS和Android上使用相同的原则.使用本文,我可以使用以下代码从ADFS请求安全令牌:

const string soapMessage =
@"<s:Envelope xmlns:s=""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"">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
        <a:To s:mustUnderstand=""1"">https://fs2.server2012.local/adfs/services/trust/13/UsernameMixed</a:To>
        <o:Security s:mustUnderstand=""1"" xmlns:o=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"">
            <o:UsernameToken u:Id=""uuid-6a13a244-dac6-42c1-84c5-cbb345b0c4c4-1"">
            <o:Username>username</o:Username>
            <o:Password Type=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"">password</o:Password>
            </o:UsernameToken>
        </o:Security>
    </s:Header>
    <s:Body>
        <trust:RequestSecurityToken xmlns:trust=""http://docs.oasis-open.org/ws-sx/ws-trust/200512"">
            <wsp:AppliesTo xmlns:wsp=""http://schemas.xmlsoap.org/ws/2004/09/policy"">
            <a:EndpointReference>
                <a:Address>https://wcfservicecertificate/wcfservice/Service.svc/wstrust</a:Address>
            </a:EndpointReference>
            </wsp:AppliesTo>
            <trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</trust:KeyType>                        
            <trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
            <trust:TokenType>urn:oasis:names:tc:SAML:2.0:assertion</trust:TokenType>
        </trust:RequestSecurityToken>
    </s:Body>
</s:Envelope>";


var webClient = new WebClient();

webClient.Headers.Add("Content-Type", "application/soap+xml; charset=utf-8");

var result = webClient.UploadString(
        address: "https://fs2.server2012.local/adfs/services/trust/13/UsernameMixed",
        method: "POST",
        data: soapMessage);
Run Code Online (Sandbox Code Playgroud)

这会产生一个SAML2.0令牌,我想在请求中发送给我们的WCF服务以进行身份​​验证.有各种来源(包括前面提到的文章)说明这应该是可能的,但我还没有找到解决方案.

任何帮助,将不胜感激.

Kuz*_*gun 1

您可以使用一种混合解决方案,该解决方案将 SAML 与 OAuth 或其他授权技术结合使用。这对于网络钓鱼技术来说更加安全。对于仅 SAML 的方法,您可以参考以下链接:如何将安全令牌从一个 wcf 服务传递到另一个 wcf 服务。据说需要saveBootstrapTokens在webconfig上启用属性。

此链接也很有用:Availability of Bootstrap Tokens