2015-04-12 29 views
2

我们的WebAPI端点使用被动WS联盟目前担保作为协议和ADFS作为STS。我们目前使用一个颇为曲折的解决办法对于restsharp客户,因为被动WS联盟确实不是最佳的非浏览器客户端,所以我们想找到一个更好的办法,以确保我们为这些类型的客户端的WebAPI的端点,而无需更换ADFS或增加额外的基础设施与ADFS使用什么协议时,对于非浏览器客户端安全的WebAPI可同时用于基于浏览器的客户端(角)和非基于浏览器的客户端(restsharp)和的WebAPI

我的理解是,OAuth2用户“资源所有者密码凭据授予”(grant_type =密码)将很好地支持此方案,但遗憾的是,目前不支持ADFS。

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

如果这是不可能的,可以使用WS-Trust和承载令牌,而不诉诸使用WCF我安全的WebAPI终点?

回答

3

事实证明这是可能使用WS-信托获得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 = @"[email protected]", Password = "[email protected]" } } 
    }; 
    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; 
    } 
} 
相关问题