SignalR 授权属性不适用于 cookie 身份验证
SignalR Authorize attribute does not work with cookie authentication
我正在使用 AspNetCore 和 cookie 中间件进行身份验证,我是这样设置的...
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = Constants.AuthenticationScheme,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/")
});
我使用登录表单成功进行了身份验证,然后重定向到标有 [Authorize] 属性的控制器。
控制器然后加载一个页面,该页面具有连接到集线器的 javascript signalR 客户端。
但是,当我添加 signalR [Authorize] 属性时。我从服务器收到 401 Unauthorized。
如何让 signalR 识别身份验证 cookie?我可以看到它已经在 Context.RequestCookies.
中传递了 cookie
否则我如何手动解密 cookie 并自己设置用户?
我通过自己解密 cookie 设法解决了这个问题,但是我对更好的方法非常感兴趣。
我在
的帮助下创建了一个帮助程序 class 来生成身份验证票证格式
public static class SecurityHelper
{
/// <summary>
/// Gets the format for the security cookie used to encrypt and decrpyt cookie
/// </summary>
/// <param name="services">The app service provider</param>
/// <returns>The authentication ticket format</returns>
public static ISecureDataFormat<AuthenticationTicket> GetTicketFormat(IServiceProvider services)
{
var authenticationType = "Cookies";
var protectionProvider = services.GetRequiredService<IDataProtectionProvider>();
var dataProtector = protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", authenticationType, "v2");
return new TicketDataFormat(dataProtector);
}
}
并告诉 cookie 中间件在我的 startup.cs class...
中使用此票证格式
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/"),
TicketDataFormat = SecurityHelper.GetTicketFormat(app.ApplicationServices)
});
然后在 this 文章的帮助下创建了我自己的信号器身份验证属性来解密 cookie 并设置用户主体。
/// <summary>
/// Attribute to have signalr hubs authenticate
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class AuthorizeHubUsersAttribute : AuthorizeAttribute
{
/// <summary>
/// Decrpyt the authentication cookie and set the user principal
/// </summary>
/// <param name="hubDescriptor">The hub descriptor</param>
/// <param name="request">The request object</param>
/// <returns>If the user is aythenticated</returns>
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, HttpRequest request)
{
var cookie = request.Cookies[".AspNetCore.Cookies"];
var ticketFormat = SecurityHelper.GetTicketFormat(request.HttpContext.RequestServices);
var authenticationTicket = ticketFormat.Unprotect(cookie);
request.HttpContext.User = authenticationTicket.Principal;
return base.AuthorizeHubConnection(hubDescriptor, request);
}
/// <summary>
/// Check the user is authenticated
/// </summary>
/// <param name="user">The user principal</param>
/// <returns>If the user is aythenticated</returns>
protected override bool UserAuthorized(IPrincipal user)
{
if (user?.Identity == null)
{
return false;
}
return user.Identity.IsAuthenticated;
}
}
然后我所要做的就是用属性
装饰我的集线器 class
[AuthorizeHubUsersAttribute()]
public class GameMessageHub : Hub<IGameMessageHub> {
....
}
我找不到将依赖项注入 signalr 属性的方法,但如果有人想出办法,我想知道。
我正在使用 AspNetCore 和 cookie 中间件进行身份验证,我是这样设置的...
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = Constants.AuthenticationScheme,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/")
});
我使用登录表单成功进行了身份验证,然后重定向到标有 [Authorize] 属性的控制器。
控制器然后加载一个页面,该页面具有连接到集线器的 javascript signalR 客户端。
但是,当我添加 signalR [Authorize] 属性时。我从服务器收到 401 Unauthorized。
如何让 signalR 识别身份验证 cookie?我可以看到它已经在 Context.RequestCookies.
中传递了 cookie否则我如何手动解密 cookie 并自己设置用户?
我通过自己解密 cookie 设法解决了这个问题,但是我对更好的方法非常感兴趣。
我在
public static class SecurityHelper
{
/// <summary>
/// Gets the format for the security cookie used to encrypt and decrpyt cookie
/// </summary>
/// <param name="services">The app service provider</param>
/// <returns>The authentication ticket format</returns>
public static ISecureDataFormat<AuthenticationTicket> GetTicketFormat(IServiceProvider services)
{
var authenticationType = "Cookies";
var protectionProvider = services.GetRequiredService<IDataProtectionProvider>();
var dataProtector = protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", authenticationType, "v2");
return new TicketDataFormat(dataProtector);
}
}
并告诉 cookie 中间件在我的 startup.cs class...
中使用此票证格式app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/"),
TicketDataFormat = SecurityHelper.GetTicketFormat(app.ApplicationServices)
});
然后在 this 文章的帮助下创建了我自己的信号器身份验证属性来解密 cookie 并设置用户主体。
/// <summary>
/// Attribute to have signalr hubs authenticate
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class AuthorizeHubUsersAttribute : AuthorizeAttribute
{
/// <summary>
/// Decrpyt the authentication cookie and set the user principal
/// </summary>
/// <param name="hubDescriptor">The hub descriptor</param>
/// <param name="request">The request object</param>
/// <returns>If the user is aythenticated</returns>
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, HttpRequest request)
{
var cookie = request.Cookies[".AspNetCore.Cookies"];
var ticketFormat = SecurityHelper.GetTicketFormat(request.HttpContext.RequestServices);
var authenticationTicket = ticketFormat.Unprotect(cookie);
request.HttpContext.User = authenticationTicket.Principal;
return base.AuthorizeHubConnection(hubDescriptor, request);
}
/// <summary>
/// Check the user is authenticated
/// </summary>
/// <param name="user">The user principal</param>
/// <returns>If the user is aythenticated</returns>
protected override bool UserAuthorized(IPrincipal user)
{
if (user?.Identity == null)
{
return false;
}
return user.Identity.IsAuthenticated;
}
}
然后我所要做的就是用属性
装饰我的集线器 class[AuthorizeHubUsersAttribute()]
public class GameMessageHub : Hub<IGameMessageHub> {
....
}
我找不到将依赖项注入 signalr 属性的方法,但如果有人想出办法,我想知道。