每个用户正确固定websockets

时间:2017-12-12 15:06:45

标签: asp.net websocket oauth-2.0

我已经在我的应用程序中实现了websockets,但目前我发现了一个潜在的安全漏洞。

websocket旨在将特定用户帐户的数据发送到浏览器,但服务器需要知道用户的AccountID才能执行此操作。目前我只是从前端发送AccountId作为queryString参数,但这显然是滥用,因为任何人都可以人为地更改其AccountID

我目前在ASP.NET后端使用ApplicationOAuthProvider进行WebAPI身份验证,但是当我将Bearer令牌设置为失败时,我无法将其与WebSocket请求一起使用。因此,我必须将我的WebSocket握手调用设置为匿名

控制器

[AllowAnonymous]
[HttpGet]
[Route("api/realtime")]
public async Task<HttpResponseMessage> RealTime()
{
    var currentContext = HttpContext.Current;

    if (currentContext.IsWebSocketRequest || currentContext.IsWebSocketRequestUpgrading)
    {
        currentContext.AcceptWebSocketRequest(this.ProcessWebSocketRequest);

        return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
    }

    return Request.CreateResponse(HttpStatusCode.BadRequest);
}

WebSocketHandler

public override void OnOpen()
{
    this.AccountId = int.Parse(this.WebSocketContext.QueryString["accountId"]);

    if (this.myClientService.ClusterClient == null)
    {
        this.myClientService
            .Start()
            .ContinueWith(async (t) =>
            {
                await this.myClient.OnWebSocketConnected(this.AccountId, this);
            });
    }
    else
    {
        var unawaitedTask = this.myClient.OnWebSocketConnected(this.AccountId, this);
    }
}

这是如何解决的?

1 个答案:

答案 0 :(得分:1)

您可以使用一次性令牌,如下所示:

首先,客户端在身份验证标头中使用承载令牌进行HTTP呼叫,作为授权或身份验证的方式。作为响应,您的应用程序返回用于建立websocket连接的URL。此网址可能类似于&#34; wss://domain.name/connect/374623618723232372"。该长随机数是一次性令牌,您可以根据需要生成并存储在数据库中,将其与授权或身份验证上下文相关联(例如,它可以是用户ID,或授予用户的任何角色或权限)

接下来,客户端使用该URL与您的应用程序建立websocket连接。发生这种情况时,您的应用程序从URL中提取该一次性令牌,在数据库中验证它尚未使用,读取授权/身份验证上下文,并将其从数据库中删除。

这样,您可以将websocket会话唯一链接到OAuth会话。