首页 文章

当非浏览器客户端的安全性webapi时,与ADFS一起使用的协议

提问于
浏览
2

我们的webapi endpoints 用于基于浏览器的客户端(角度)和非基于浏览器的客户端(restsharp),webapi目前使用被动WS-Federation作为协议和ADFS作为STS进行保护 . 我们目前对restsharp客户端使用了一个相当复杂的解决方法,因为被动WS-Federation对于非浏览器客户端来说真的不是最佳的,因此我们希望找到一种更好的方法来保护这些类型客户端的webapi endpoints ,而无需替换ADFS或添加额外的基础设施

我的理解是OAuth2“资源所有者密码凭据授权”(grant_type =密码)将很好地支持这种情况,但遗憾的是ADFS目前不支持它 .

所以,我的问题是,有没有一种很好的方法来使用ADFS支持的一个OAuth2流,即“授权代码授权流”(grant_type = authorization_code)来支持非基于浏览器的客户端?

如果无法做到这一点,我是否可以使用WS-Trust和承载令牌来保护WebApi endpoints ,而无需使用WCF?

1 回答

  • 4

    事实证明,可以使用WS-Trust获取saml 2.0令牌,并使用WebApi在Thinktecture IdentityModel的帮助下使用它 . 以下内容不包括声明转换,因此如果您需要向委托人添加声明,则需要进行更多工作 .

    webapi服务的owin启动需要使用Thinktecture.IdentityModel.Owin中的以下内容:

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

    让客户端从ADFS请求saml 2.0令牌

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

    并为客户端调用服务(使用HttpClient但RestSharp也可以)

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

相关问题