2008-09-11 6 views
13

WCF 서비스 (BasicHttpBinding)와 통신하는 Silverlight 2 응용 프로그램을 작성했습니다. Silverlight 콘텐츠를 호스팅하는 사이트는 ASP.NET 멤버 자격 공급자를 사용하여 보호됩니다. 내 WCF 서비스에서 HttpContext.Current.User.Identity.Name을 사용하여 현재 사용자에게 액세스 할 수 있으며 AspNetCompatibilityRequirementsMode를 켰습니다.WCF, ASP.NET 멤버십 공급자 및 인증 서비스

이제 똑같은 웹 서비스를 사용하여 Windows 응용 프로그램을 작성하려고합니다. 인증을 처리하기 위해 Authentication service을 사용하고 "login"을 호출하여 내 사용자를 인증 할 수 있습니다 ... Okey, all good ...하지만 어떻게 다른 서비스 클라이언트에 설정된 인증 쿠키를 얻을 수 있습니까?

두 서비스는 동일한 도메인에서 호스팅되는

  • MyDataService.svc < - 내 데이터를 다루는 일
  • AuthenticationService.svc < - 윈도우 응용 프로그램이 인증을 호출 할 수있는 일.
나는 윈도우 클라이언트에 대한 새로운 서비스를 만들거나 다른 바인딩을 사용하지 않으

...

클라이언트 응용 프로그램 서비스 는 다른 대안이지만, 모든 예제는 방법을 보여 제한 사용자, 역할 및 프로필을 가져옵니다.하지만 일단 클라이언트 응용 프로그램 서비스를 사용하여 인증을 받으면 동일한 서버에 다시 전화를 걸 때 인증 쿠키를 내 서비스 클라이언트에 첨부하는 방법이 있어야합니다.

솔루션이있는 wsHttpBinding의 엔드 포인트를 추가 동료의 의견에 따르면

,하지만 난 그 주위를 얻을 수 있습니다 ... 같은 WCF에 의해 생성 된 것과 같은

답변

5

마침내이 작업을 수행 할 수있는 방법을 발견했습니다. 인증을 위해 "WCF Authentication Service"을 사용하고 있습니다. 서비스를 인증 할 때 인증 쿠키를 설정하려고합니다. 응답에서이 쿠키를 가져와 동일한 컴퓨터의 다른 웹 서비스에 대한 다른 요청에 추가해야합니다. 이 작업을 수행하는 코드는 다음과 같습니다

var authService = new AuthService.AuthenticationServiceClient(); 
var diveService = new DiveLogService.DiveLogServiceClient(); 

string cookieHeader = ""; 
using (OperationContextScope scope = new OperationContextScope(authService.InnerChannel)) 
{ 
    HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty(); 
    OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty; 
    bool isGood = authService.Login("jonas", "jonas", string.Empty, true); 
    MessageProperties properties = OperationContext.Current.IncomingMessageProperties; 
    HttpResponseMessageProperty responseProperty = (HttpResponseMessageProperty)properties[HttpResponseMessageProperty.Name]; 
    cookieHeader = responseProperty.Headers[HttpResponseHeader.SetCookie];     
} 

using (OperationContextScope scope = new OperationContextScope(diveService.InnerChannel)) 
{ 
    HttpRequestMessageProperty httpRequest = new HttpRequestMessageProperty(); 
    OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, httpRequest); 
    httpRequest.Headers.Add(HttpRequestHeader.Cookie, cookieHeader); 
    var res = diveService.GetDives(); 
}  

당신은 내가 두 서비스 클라이언트, 인증 서비스 FO 하나, 내가 실제로 사용하는거야 서비스에 대한 하나가 볼 수 있듯이. 첫 번째 블록은 Login 메소드를 호출하고 인증 쿠키를 응답에서 가져옵니다. 두 번째 블록은 "GetDives"서비스 메소드를 호출하기 전에 헤더를 요청에 추가합니다.

나는이 코드에 전혀 만족하지 않고 "Service Reference"대신 "Web Reference"를 사용하고 대신 .NET 2.0 스택을 사용하는 것이 더 좋은 대안이라고 생각합니다.

2

웹 서비스를 희망하고있다는 종종 가장 사용 "상태 비 저장"방식으로, 웹 서비스 호출이 새로 시작됩니다. 이렇게하면 클라이언트의 상태를 호출하는 "세션"이 필요 없으므로 서버 코드가 단순 해집니다. 또한 티켓, 쿠키 또는 서버 상태에 대한 정보를 담고있는 다른 geegaw를 보유 할 필요가 없으므로 클라이언트 코드가 간단 해집니다.

설명 된 방식으로 두 가지 서비스를 생성하면 상태 유지가 도입됩니다. 클라이언트는 "인증 됨"또는 "인증되지 않음"이며 MyDataService.svc는 어느 것을 파악해야합니다.

회원 기관이 전화를 인증 할 때 WCF가 제대로 작동하는 것으로 나타났습니다. 따라서 주어진 예제에서 MyDataService의 서비스 구성에 멤버 자격 공급자 인증 gubbins를 추가하고 별도의 인증 서비스는 필요가 없습니다.

자세한 내용은 MSDN 문서 here (영문)을 참조하십시오.

[나에게 게으르다는 점은 이것이 완전히 선언적이라는 것입니다. 응용 프로그램에 대한 app.config의 MembershipProvider에 대한 올바른 구성 항목을 간단히 분산시킵니다. 빙고! 서비스의 모든 계약에 대한 모든 호출이 인증됩니다.]

이것은 특히 빠르지 않을 것입니다. 인증 데이터베이스로 SQL Server를 사용하는 경우 서비스 호출 당 적어도 하나의 저장 프로 시저 호출이 있어야합니다. 대부분의 경우 (특히 HTTP 바인딩의 경우) 서비스 호출의 오버 헤드가 커집니다. 그렇지 않은 경우 인증 요청을 캐시하는 멤버 자격 공급자 구현을 고려해보십시오.

이 제공하지 않는 한 가지가은 "로그인"기능을 제공하는 기능입니다. 이를 위해 아무것도하지 않는 (인증이 실패한 경우를 제외하고) 아무것도하지 않는 (인증 된!) 서비스 계약을 제공하거나 원래 참조 된 조항에 설명 된대로 멤버 자격 공급자 서비스를 사용할 수 있습니다.

0

Custom Message Inspector & 동작 뒤에 추가 코드가 많이 숨겨져있어 OperationContextScope를 직접 조작 할 필요가 없습니다.

나는 나중에 무언가를 조롱하고 그것을 당신에게 보냅니다.

--larsw

당신은 System.Net에서 CookieContainer 객체를 살펴한다
+1

훌륭한 Lars 소리가납니다. 우리가 "이 빨판을 닫을 수있는 좋은 예를 들어주세요") 건배, 조나 스 –

0

. 이 개체를 사용하면 브라우저가 아닌 클라이언트가 쿠키에 매달릴 수 있습니다. 이것은 우리 팀이 마지막으로 우리가 그 문제에 부딪쳤을 때 사용한 것이다.

Here is a brief article 사용 방법에 대해 알아보십시오. 거기에 더 좋은 것들이 있을지 모르지만 이것은 당신을 시작해야합니다.

우리는 현재 WCF 서비스 집합과 Silverlight 2 응용 프로그램에 대한 무국적 경로를 방문했습니다. Silverlight 2에서 TransportWithMessageCredential 보안으로 바인딩 된 서비스를 사용할 수는 있지만 Silverlight 측에서 사용자 지정 보안 코드가 필요합니다. 결론은 모든 응용 프로그램이 메시지 헤더에 사용자 이름과 암호를 설정하여 서비스에 액세스 할 수 있다는 것입니다. 이는 개발자가 직접 값을 설정하는 것에 대해 걱정할 필요가 없도록 사용자 지정 IRequestChannel 구현에서 한 번 수행 할 수 있습니다. WCF는 개발자가 serviceProxy.Security.Username 및 serviceProxy.Security.Password 또는 똑같이 간단하다고 생각하는 일을 쉽게 수행 할 수 있습니다.

0

클라이언트 응용 프로그램 서비스를 사용하여 웹 서비스를 인증 할 때이 글을 작성하는 동안 잠시 썼습니다. 메시지 속성을 사용하여 쿠키 헤더를 삽입합니다. 문서 및 데모 프로젝트가 포함 된 단어 파일이 있습니다. 그게 정확히 당신이하고있는 것은 아니지만 그 꽤 가까운 것입니다. here에서 다운로드 할 수 있습니다. 클라이언트에

1

이 포함 (< 내부는 system.serviceModel >을) 서비스에 대한 귀하의 < 바인딩 > 태그를 수정 allowCookies는 = "true"를

응용 프로그램은 이제 쿠키를 유지하고 사용해야합니다. 로그인 한 후 IsLoggedIn이 true를 반환한다는 것을 알 수 있습니다. 쿠키를 허용하지 않으면 false를 반환합니다.