SignalR을 사용하여 WebAPI 서버 백엔드에서 JavaScript 웹 페이지로 메시지를 중계합니다. 이러한 메시지는 특정 사용자에게만 전달되므로 SignalR ConnectionId를 웹 페이지 사용자의 사용자 정의 ID와 매핑해야합니다.SignalR : OnConnected를 포함한 모든 통화에서 사용자 정의 ID 받기
현재 WebAPI는 FormsAuthentication을 사용하며 필요한 사용자 지정 ID는 쿠키에 있습니다.
처음에 나는 쿠키 떨어져 값을 가져 오도록 IUserIdProvider을 상속 : 올바르게 사용자 ID를 점점 늘어나는만큼 일public class CustomIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
Cookie formsAuthCookie = request.Cookies[FormsAuthentication.FormsCookieName];
try
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsAuthCookie.Value);
var obj = JsonConvert.DeserializeObject(ticket.Name) as JObject;
return (string)obj.GetValue("UserId");
}
catch (Exception)
{
return null;
}
}
}
. 그러나 그 가치는 내가 말할 수있는 한 정체성에 결코 정해지지 않았습니다. Context.User.Identity.Name으로 인해 Identity 값을 편집 할 수 없었습니다. 모두 읽기 전용입니다.
편집 : CustomIdProvider를 다시 시도하면 GetUserId 메서드에서 반환 할 때 올바르게 값을 가져 오지만 OnConnected는 호출되지 않습니다.
내 다음 접근 방식은 Shaun Xu의 블로그 포스트 Set Context User Principal For Customized Authentication In SignalR을 기반으로했습니다. 여기 내 구현 :
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
private const string CUSTOM_IDENTITY_KEY = "server.User";
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
string customId;
// This gets the custom id from the cookie.
TryGetCustomId(request, out customId);
// The CustomIdentity class just sets the customId to the name.
request.Environment.Add(CUSTOM_IDENTITY_KEY, new ClaimsPrincipal(new CustomIdentity(customId, true)));
return true;
}
public override bool AuthorizeHubMethodInvocation(IHubIncomingInvokerContext hubIncomingInvokerContext, bool appliesToMethod)
{
string connectionId = hubIncomingInvokerContext.Hub.Context.ConnectionId;
IDictionary<string, object> environment = hubIncomingInvokerContext.Hub.Context.Request.Environment;
object obj;
environment.TryGetValue(CUSTOM_IDENTITY_KEY, out obj);
var principal = obj as ClaimsPrincipal;
if (principal?.Identity == null || !principal.Identity.IsAuthenticated)
{
return false;
}
hubIncomingInvokerContext.Hub.Context = new HubCallerContext(new ServerRequest(environment), connectionId);
return true;
}
이 실제로 두 가지 방법이 호출 될 때 올바르게 Context.User.Identity을 설정하기 위해 노력하고 있습니다.
그러나 내 문제는 사용자가 처음에 연결하고 OnConnected를 호출 할 때 AuthorizeHubMethodInvocation을 호출하지 않고 따라서 OnConnected에서 Context.User.Identity를 사용할 수 없다는 것입니다.
SignalR 허브의 모든 단계 (OnConnected, OnDisconnected 및 invoked 메소드)에서 내 사용자 정의 ID를 포함하는 올바른 ID에 액세스 할 수 있기를 원합니다.
아무에게도 좋은 해결책이 있습니까?
세션에있는 항목을 다른 위치 (예 : 캐시 또는 데이터베이스)에 저장하는 대신 세션 ID로 연결 ID를 사용하는 것이 어떻습니까? 그런 다음 인증이 발생하기 전에 사용자를 추적 한 다음 해당 사용자를 인증하자마자 세션을 통해 메타 데이터를 추가 할 수 있습니다 – tommed