2014-02-24 3 views
2

ADFS를 통해 인증하는 웹 응용 프로그램 및 웹 API 서비스가 있습니다. 이들은 동일한 IIS 응용 프로그램에 포함되어 있으며 웹 응용 프로그램은 문제없이 웹 API 서비스에 다시 호출합니다.웹 API 호출에 SAML 토큰 전달

다른 응용 프로그램에서 동일한 서비스를 호출하려고하는데 토큰을 전달하는 데 문제가 있습니다. 나는 다음과 같은 코드를 가진 SAML 토큰을 인증하고 검색 할 수 있어요 :

var stsEndpoint = "https://MyAdfsServer/adfs/services/trust/13/UsernameMixed"; 
var reliantPartyUri = "https://MyDomain/AppRoot/"; 

var factory = new Microsoft.IdentityModel.Protocols.WSTrust.WSTrustChannelFactory(
      new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), 
      new EndpointAddress(stsEndpoint)); 

factory.TrustVersion = System.ServiceModel.Security.TrustVersion.WSTrust13; 

// Username and Password here... 
factory.Credentials.UserName.UserName = @"Domain\UserName"; 
factory.Credentials.UserName.Password = "Password"; 

var rst = new RequestSecurityToken 
    { 
     RequestType = RequestTypes.Issue, 
     AppliesTo = new EndpointAddress(reliantPartyUri), 
     KeyType = KeyTypes.Bearer, 
    }; 

var channel = factory.CreateChannel(); 
var token = channel.Issue(rst) as GenericXmlSecurityToken; 

var saml = token.TokenXml.OuterXml; 

그러나, 나는 웹 API를 호출에 SAML을 전달하는 방법을 모르겠어요. 나는 이것을 시도했다 :

using (var handler = new HttpClientHandler() 
    { 
     ClientCertificateOptions = ClientCertificateOption.Automatic, 
     AllowAutoRedirect = false 
    }) 
{ 
    using (var client = new HttpClient(handler)) 
    { 
     client.BaseAddress = new Uri("https://MyDomain/AppRoot/api/"); 

     client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SAML", saml); 

     HttpResponseMessage response = client.GetAsync("MyService/Get/").Result; 

     // Get the results... 
     var result = response.Content.ReadAsStringAsync().Result; 
     var status = response.StatusCode; 
    } 
} 

이 302 상태 코드를 반환하고 인증을위한 ADFS 서버로 나를 리디렉션을 시도하고 있습니다. 웹 API 서비스에 SAML 토큰을 전달하는 또 다른 방법이 있습니까?

+0

SAML 토큰 및 REST API를 함께 잘 재생되지 않습니다. OAuth 2.0 사용을 고려하십시오. –

+0

Windows Server 2008 R2가 있고 Oauth 2.0을 사용할 수 없기 때문에 동일한 문제가 발생합니다. 어떻게 처리 했습니까? –

+0

아니요, Windows 인증을 통해 인증 된 별도의 IIS 응용 프로그램을 만들어 필요한 서비스를 노출했습니다. 최선의 해결책은 아니지만 우리의 요구에 부합합니다. –

답변

1

나는 동일한 도전에 달려있다. 문제의 핵심은 SAML이 SOAP을 기반으로하는 사양이라는 것입니다. 전송과 상관없이 여러 SOAP 처리 노드에서 메시지를 보호하기위한 것입니다.

반면에 REST는 모두 운송에 관한 것입니다. 따라서 REST 엔드 포인트의 보안은 전송 보안 (예 : SSL)에 달려있다.

우리는 "saml_user"와 같이 고정 된 사용자 이름으로 NetworkCredential을 사용하고 SAML 토큰에 암호를 설정하는 "해킹"을 구현했습니다. 그러나 이것은 단기적인 것입니다. 모든 통화에 8 ~ 10KB를 실제로 추가 하시겠습니까?

단순 웹 토큰은 REST 보안에 훨씬 적합합니다. 사실 Microsoft의 클레임 기반 ID 및 액세스 제어 가이드 (제 2 판)에는 SAML 토큰 공급자에서 단순 웹 토큰으로 브리징하는 전체 장이 포함되어 있습니다. Accessing REST Services from a Windows Phone Device을 참조하십시오.

1

(SET)

  string samlString = "blah blah blah"; 

      byte[] bytes = Encoding.UTF8.GetBytes(samlString); 

      string base64SamlString = Convert.ToBase64String(bytes); 

      myHttpClient.DefaultRequestHeaders.Add("X-My-Custom-Header", base64SamlString); 

(GET)

 IEnumerable<string> headerValues = request.Headers.GetValues("X-My-Custom-Header"); 

     if (null != headerValues) 

     { 

      var encoding = Encoding.GetEncoding("iso-8859-1"); 

      string samlToken = encoding.GetString(Convert.FromBase64String(headerValues.FirstOrDefault())); 

     } 
+0

이 접근법은 내가 encoding.GetString을 호출 할 때'error 411 : Length required'를주었습니다 –

+0

"headerValues.FirstOrDefault()"의 문자열 길이는 얼마입니까? – granadaCoder

+0

죄송합니다. 데이터를 POST 데이터 (즉 헤더가 아닌)로 인코딩하고 해당 코드를 잃어 버렸습니다. –