代码之家  ›  专栏  ›  技术社区  ›  Wraith

ServiceStack ServerEvents身份验证配置

  •  2
  • Wraith  · 技术社区  · 7 年前

    我正在尝试对ServiceStack ServerEvents使用JWT身份验证,以确保所有用户都经过身份验证,但我找不到如何配置服务器事件来实现这一点。我假设这在默认配置下可以工作,因为文档中没有提到如何使其工作,只是它可以工作,这意味着我的配置中有一些东西禁用/破坏了此功能,但我不知道是什么。

    在服务器端,Configure()中的设置非常简单。

    this.Plugins.Add(
        new AuthFeature(
            () => { return new AuthenticatedSession(); },
            new IAuthProvider[] { jwt, perpetualJwt }
        )
        {
            IncludeAssignRoleServices = false,IncludeRegistrationService = false
        }
    );
    
    this.Plugins.Add(
        new ServerEventsFeature
        {
            StreamPath = ApiHost.EventSystemRoot +"-stream", // /request/event-stream
            HeartbeatPath = ApiHost.EventSystemRoot + "-heartbeat",
            UnRegisterPath = null,
            SubscribersPath = null,
            LimitToAuthenticatedUsers = true,
            IdleTimeout = TimeSpan.FromSeconds(30),
            HeartbeatInterval = TimeSpan.FromSeconds(20),
            NotifyChannelOfSubscriptions = true,
        }
    );
    

    jwt和PerformalJWT提供程序是JsonWebTokeynAuthProviders(handle bearer token jwt),我已经将它们用于标准servicestack api请求,因此我相信它们的函数是正确的,但它们可能不会被调用。

    要连接客户端,我使用如下代码:

    this.directBoardClient = new JsonServiceClient(this.boardUrlTextBox.Text)
    {
        BearerToken = this.boardTokenTextBox.Text
    };
    this.directBoardEvents = new ServerEventsClient(this.boardUrlTextBox.Text.AppendPath("ueib", "request"))
    {
        OnMessage = boardEvents_OnMessage,
        OnCommand = boardEvents_OnCommand
    };
    this.directBoardEvents.ServiceClient=this.directBoardClient;
    this.directBoardEvents.Start();
    

    当我给start打电话时,我得到了401。如果我不需要身份验证或省略了serverevents客户端,directBoardClient可以成功进行需要身份验证的调用。

    我认为,当我连接到流端点时,身份验证功能没有被调用,并且我移动事件端点可能会干扰某些内容,但我无法确定这是什么。是否有人可以帮助确定我可以做些什么来修复此问题或建议进一步的调试步骤?

    1 回复  |  直到 7 年前
        1
  •  3
  •   mythz    7 年前

    这个 ServerEventsClient.ServiceClient 不用于建立服务器事件连接,仅用于 CookieContainer is shared 这将允许您通过 ServiceClient 建立 Authenticated Session .

    如果您使用的是JWT AuthProvider,您可以 send it inside a Cookie 因此,它与客户端Web请求一起发送。否则,您可以尝试使用 EventStreamRequestFilter 在建立服务器事件连接之前执行,例如:

    new ServerEventsClient(...) {
        EventStreamRequestFilter = req => req.AddBearerToken(jwt)
    }
    

    或者I just added support 对于 ResolveStreamUrl 这将允许您修改用于建立服务器事件连接的URL,这也将允许您将JWT令牌添加到查询字符串中,如下所示 seen in the JWT TypeScript ServerEventsClient example

    var sseClient = new ServerEventsClient(BaseUrl, ["*"], {
        resolveStreamUrl: url => appendQueryString(url, { "ss-tok": JWT }),
        handlers: {
            onConnect: e => { 
                console.log(e.isAuthenticated /*true*/, e.userId, e.displayName);
            }
        }
    }).start();
    

    此更改还允许您修改 EventStreamPath 独立于 BaseUri 之前假设为 {BaseUrl}/event-stream .

    ResolveStreamUrl+EventStreamPath可从现在的v5.0.3中获得 available on MyGet .

    这要求您的JWT AuthProvider通过查询字符串接受JWT令牌,您可以通过以下方式在ServiceStack的JWT AuthProvider中启用该查询字符串:

    new JwtAuthProvider {
        AllowInQueryString = true
    }