what protocol to use with ADFS when security webapi for non-browser clients

匆匆过客 提交于 2019-12-02 04:02:06

问题


Our webapi endpoints are used for both browser based clients (angular) and non-browser based clients (restsharp) and the webapi are currently secured using passive WS-Federation as the protocol and ADFS as the STS. We currently use a rather convoluted workaround for the restsharp clients since passive WS-Federation really isn't optimal for non-browser clients so we would like to find a better way to secure our webapi endpoints for these types of clients without having to replace ADFS or add extra infrastructure.

My understanding is that OAuth2 "Resource Owner Password Credentials Grant" (grant_type=password) would support this scenario nicely but unfortunately it is currently not supported by ADFS.

So, my question is this, is there a nice way to use the one OAuth2 flow that ADFS supports, namely "Authorization Code Grant Flow" (grant_type=authorization_code) to support non-browser based clients?

If this is not possible, can I secure WebApi endpoints using WS-Trust and bearer tokens without resorting to using WCF?


回答1:


It turns out it was possible to use WS-Trust to get a saml 2.0 token and a WebApi to consume it with a little help from Thinktecture IdentityModel. The following does not include claims transformation so if you need to add claims to the Principal, then a little more work is needed.

The owin startup for the webapi service needs to use the following from Thinktecture.IdentityModel.Owin:

app.UseSaml2BearerAuthentication(
            audience: new Uri(ConfigurationManager.AppSettings["FederatedSecurity.Realm"]),
            issuerThumbprint: ConfigurationManager.AppSettings["FederatedSecurity.Thumbprint"],
            issuerName: ConfigurationManager.AppSettings["FederatedSecurity.Authority"]);

For the client to request the saml 2.0 token from ADFS

private static SecurityToken RequestSecurityToken()
{
    var trustChannelFactory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), new EndpointAddress(new Uri("https://yourAdfsServer/adfs/services/trust/13/usernamemixed"), new AddressHeader[0]))
    {
        TrustVersion = TrustVersion.WSTrust13,
        Credentials = { UserName = { UserName = @"u$ern@me", Password = "p@ssw0rd" } }
    };
     var requestSecurityToken = new RequestSecurityToken
    {
        RequestType = RequestTypes.Issue,
        KeyType = KeyTypes.Bearer,
        TokenType = TokenTypes.Saml2TokenProfile11,
        AppliesTo = new EndpointReference(_audience)
    };

    RequestSecurityTokenResponse response;
    var securityToken = trustChannelFactory.CreateChannel().Issue(requestSecurityToken, out response);

    return securityToken;
}

And for the client to call the service (using HttpClient but RestSharp will also work)

private static void CallService(SecurityToken token)
{
    using (HttpClient client = new HttpClient())
    {
        client.SetBearerToken(Convert.ToBase64String(Encoding.UTF8.GetBytes(token.ToTokenXmlString())));
        var httpMessage = client.GetAsync(new Uri(_restEndpoint)).Result;
    }
}


来源:https://stackoverflow.com/questions/29593077/what-protocol-to-use-with-adfs-when-security-webapi-for-non-browser-clients

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!