2013-01-04 3 views
5

기본 인증을 구현하는 Asp.Net에서 ServiceStack 서비스를 생성했습니다. 서비스 경로에서 모든 것이 잘 작동합니다. 로그인 할 수 있으며 이후의 호출에서 유효성이 확인되는 세션 쿠키를 얻을 수 있습니다. 나는 그 요청에 대해 HttpClient를 사용하고있다.ServiceStack 인증 플러그인을 사용하여 SignalR Hub 인증

같은 Asp.Net 서비스에서 실행되지만 주체가 내 허브 메서드에서 인증되지 않은 SignalR 허브가 있습니다.

기본적으로 ServiceStack은 내 허브에 대한 호출을 가로 채어 세션 쿠키의 유효성을 검사하고 Context.User.Identity를 채우고 인증 된 것으로 표시해야합니다. 이 설정을 얻을 수 있다면 허브에있는 간단한 [Authorize] 속성으로 나머지 작업을 수행 할 수 있습니다. 내 세션 쿠키는 각 호출에 허브로 전송이 설정 한 후

// set up a HttpClient with a cookie container to hold the session cookie 
var cookieJar = new CookieContainer(); 
var handler = new HttpClientHandler { CookieContainer = cookieJar, UseCookies = true, UseDefaultCredentials = false }; 

var client = new HttpClient(handler) { BaseAddress = _baseUri }; 

client.DefaultRequestHeaders.Authorization = 
new AuthenticationHeaderValue("Basic", 
    Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password)))); 

// do client login and get response with session cookie... 
var response = client.PostAsync(...); 

// add the cookies to the SignalR hub connection 
var responseCookies = cookieJar.GetCookies(_baseUri); 
var cookieContainer = new CookieContainer(); 
foreach (Cookie cookie in responseCookies) 
{ 
    cookieContainer.Add(cookie); 
} 
_hubConnection = new HubConnection(_baseUri.ToString()) { CookieContainer = cookieContainer }; 

: 여기

내 코드의 샘플입니다. 어떻게 든 ServiceStack이 요청을 가로 채고 인증 된 사용자를 설정해야합니다.

답변

6

ServiceStack이 인증을 수행하고 사용자 세션을 지속하도록하십시오. 그런 다음 인증을 필요로하는 SignalR 허브 엔드 포인트에서이 코드를 넣어 :

var cache = AppHostBase.Resolve<ICacheClient>(); 
var sess = cache.SessionAs<AuthUserSession>(); 
if (!sess.IsAuthenticated) 
    throw new AuthenticationException(); 
+0

이는 인증 쿠키를 SignalR 쿠키 컨테이너에 저장 한 원래 게시 된 코드와 함께 작동했습니다. 감사! – Kevin

2

요한의 대답은 작동하지만이 모든 방법이 코드를 넣어 당신이 허브 생성자에 넣어 경우, 그것은 실패 할 것이다 매우 편리하지 않습니다 "싱글 톤을 통해 액세스 할 수있는 ASP.NET 요청 만 지원됩니다."예외가 발생한 페이지 새로 고침 웹.

대신 허브 및 메서드 호출 권한을보다 효율적으로 제어 할 수있는 사용자 지정 특성을 만들도록 선택했습니다. 당신이 볼 수 있듯이

[AttributeUsage(AttributeTargets.Class, Inherited = false)] 
public class AuthorizeServiceStack : AuthorizeAttribute 
{ 
    public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request) 
    { 
     return CheckAuthorization(); 
    } 

    public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod) 
    { 
     return CheckAuthorization(); 
    } 

    private static bool CheckAuthorization() 
    { 
     var cache = AppHostBase.Resolve<ICacheClient>(); 
     var sess = cache.SessionAs<AuthUserSession>(); 
     return sess.IsAuthenticated; 
    } 

} 

이 코드는 요한의 대답과 동일하지만 HttpContext.Current가 null이 아닌 것을 보장뿐만 아니라 웹에서 작동합니다 :

간단한 속성은 다음과 같을 것 캐시를 호출 할 때 .SessionAs

관련 문제