SignalR授权属性不适用于Cookie身份验证



我正在使用aspnetcore和cookie中间件进行身份验证,我这样设置了...

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = Constants.AuthenticationScheme,
    AutomaticAuthenticate = true,
    AutomaticChallenge = true,
    LoginPath = new PathString("/")
});

我正在使用登录表单成功进行身份验证,然后重定向到具有[授权]属性标记的控制器。

然后,控制器加载一个具有JavaScript Signalr客户端的页面,其中连接到集线器。

但是,当我添加signalr [授权]属性时。我从服务器未经授权获得了401个。

如何使Signalr识别身份验证cookie?我可以看到它已经在上下文中通过了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类中使用此售票格式...

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
            AuthenticationScheme = "Cookies",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            LoginPath = new PathString("/"),
            TicketDataFormat = SecurityHelper.GetTicketFormat(app.ApplicationServices)
});

,然后在本文的帮助下创建了我自己的SignalR身份验证属性来解密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;
    }
}

然后我要做的就是用属性装饰我的集线器课程

[AuthorizeHubUsersAttribute()]
public class GameMessageHub : Hub<IGameMessageHub> {
 ....
}

我找不到将依赖项注入信号属性的方法,但是如果有人想知道它。

最新更新