6

我正在寻找有关如何在自托管(非 IIS)环境中运行的后端服务上实现 SignalR 授权安全的一些指导,该环境是从 Web 应用程序调用的。后端应用程序基本上是一个将 SignalR 事件触发回基于 HTML 的客户端的监视器。这一切都很好(实际上非​​常好)。

但是,我们需要限制来自 Web 站点的经过身份验证的用户对服务器的访问。所以基本上如果一个用户在网站上通过了身份验证,我们需要以某种方式在后端应用程序中获取凭据(用户名就足够了)和验证状态来决定是否允许连接以避免未经授权的访问。

任何人都可以指出一些关于如何完成这种身份验证转发的策略或模式吗?

4

2 回答 2

3

我在这里遇到了类似的问题,因为在我的网络应用程序中,我使用了一个简单的 cookie 身份验证系统,它使用 AoP 样式方法来检查任何具有属性的控制器,然后将获取当前上下文(无论是来自静态 HttpContext.Current 还是根据拦截器的类型从目标调用对象),然后验证 cookie 是否存在,它包含正确的数据,然后最后用数据库或缓存等验证令牌。

无论如何,这种方法也可以用于 Signalr,尽管它有点冗长并且您正在使用依赖注入。您基本上将使用所需属性包装集线器调用,然后设置您的 DI/IoC 配置以拦截这些调用,然后在拦截器中获取集线器实例并从请求中获取 cookie(或您的自定义身份验证机制),验证它是否全部有效,如果不是,则抛出一个new HttpException("403", "Not authenticated");应该用户踢出并在它甚至击中您的集线器方法之前返回的,这样您就可以将逻辑放在一个地方(您的拦截器或拦截器消耗的类) 然后只需使用您的属性包装需要使用此身份验证的任何方法。

我使用 Ninject 和拦截扩展,但是现在大多数主要的 DI 框架都有某种形式的 IoC 插件/扩展,例如 Autofac、Windsor、Spring 等。

如果您不喜欢将 DI 和/或 AOP 引入当前项目的路线,那么也许您可以创建一个包含身份验证逻辑的自定义集线器实例,然后在集线器中使用它,所以好吧,您仍然会从要保护的每个集线器方法中手动调用一些身份验证逻辑,但代码较少,例如:

public class AuthorisableHub : Hub
{
    private ISomeAuthenticationToken GetSomeAuthenticationTokenFromRequest(Request request) // probably a SignalR specific request object
    {
        // Get your token from the querystring or cookie etc
    }

    private bool IsAuthenticationTokenValid(ISomeAuthenticationToken token)
    {
        // Perform some validation, be it simple or db based and return result
    }

    protected void PerformUserAuthentication()
    {
        var token = GetSomeAuthenticationTokenFromRequest(Context.Request);
        var isRequestValid = IsAuthenticationTokenValid(token);

        if(!isRequestValid)
        { throw new HttpException(403, "<Some forbidden message here>"); }
    }
}

public class MyFancyPantsHub : AuthorisableHub
{
    public void TellAllClientsSomethingSecret(ISecret secret)
    {
        PerformUserAuthentication();

        // Do stuff with the secret as it should have bombed the user out
        // before it reaches here if working correctly
    }
}

它并不完美,但会起作用(我认为),而且我确信我曾经在某处读到过为每个请求新实例化集线器,如果这确实是真的,如果你想的话,你可以把这个逻辑放在你的构造函数中将身份验证应用于集线器内的每个操作。

希望对您有所帮助,或给您一些想法……有兴趣知道您最终是如何解决它的。

于 2013-07-18T09:49:02.657 回答
2

SignalR 不提供任何额外的身份验证功能。相反,它旨在与您的应用程序的身份验证机制一起使用。

集线器

您应该像往常一样进行身份验证,然后使用 SignalR 提供的 Authorize 属性在集线器上强制执行身份验证结果。

Authorize 属性可以应用于整个 Hub 或 Hub 中的特定方法。一些例子:

  • [Authorize] – 仅经过身份验证的用户
  • [Authorize(Roles = "Admin,Manager")] – 仅在指定的 .NET 角色中经过身份验证的用户
  • [Authorize(Users = "user1,user2")] – 仅具有指定用户名的经过身份验证的用户

您还可以通过在 Application_Start 方法中添加以下方法来要求所有 Hub 要求身份验证:

GlobalHost.HubPipeline.RequireAuthentication();

持久连接

您可以在请求中使用用户对象来查看用户是否经过身份验证:

request.User.IsAuthenticated

于 2013-04-07T01:23:03.997 回答