【问题标题】:what protocol to use with ADFS when security webapi for non-browser clients非浏览器客户端的安全 webapi 时与 ADFS 一起使用什么协议
【发布时间】:2015-04-12 18:35:13
【问题描述】:

我们的 webapi 端点用于基于浏览器的客户端 (angular) 和非基于浏览器的客户端 (restsharp),并且 webapi 当前使用被动 WS-Federation 作为协议和 ADFS 作为 STS 来保护 webapi。我们目前对 restsharp 客户端使用一种相当复杂的解决方法,因为被动 WS-Federation 对于非浏览器客户端确实不是最佳选择,因此我们希望找到一种更好的方法来保护这些类型的客户端的 webapi 端点,而不必替换 ADFS或添加额外的基础设施。

我的理解是 OAuth2“资源所有者密码凭据授予”(grant_type=password) 可以很好地支持这种情况,但不幸的是 ADFS 目前不支持它。

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

如果这不可能,我是否可以使用 WS-Trust 和不记名令牌来保护 WebApi 端点而不使用 WCF?

【问题讨论】:

    标签: asp.net-web-api adfs ws-federation ws-trust


    【解决方案1】:

    事实证明,在 Thinktecture IdentityModel 的帮助下,可以使用 WS-Trust 获取 saml 2.0 令牌和 WebApi 来使用它。以下不包括声明转换,因此如果您需要向 Principal 添加声明,则需要做更多的工作。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多