【问题标题】:SignalR Authorize attribute does not work with cookie authenticationSignalR Authorize 属性不适用于 cookie 身份验证
【发布时间】:2017-07-27 23:46:41
【问题描述】:

我正在使用 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 并自己设置用户?

【问题讨论】:

    标签: asp.net-core signalr .net-core


    【解决方案1】:

    我设法通过自己解密 cookie 来解决这个问题,但是我会对更好的方法非常感兴趣。

    Question 的帮助下,我创建了一个帮助类来生成身份验证票证格式

    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)
    });
    

    然后在this文章的帮助下创建了我自己的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> {
     ....
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      相关资源
      最近更新 更多