Home > Net >  AbpSession always return null when start using Websocket
AbpSession always return null when start using Websocket

Time:09-07

I'm using asp.net boilerplate framework, and I'm trying to set the WebSocket connection to become match the logged-in user id when the user establishes the WebSocket connection, but what I noticed is the AbpSession.UserId value is always null, so what is the reason, although in other classes it is working fine, and here is my code:


 public class WebSocketServerConnectionManager : ITransientDependency
    {

        private ConcurrentDictionary<string, WebSocket> _socket = new ConcurrentDictionary<string, WebSocket>();

        public IAbpSession AbpSession { get; set; }

        public WebSocketServerConnectionManager()
        {
            AbpSession = NullAbpSession.Instance;

        }

        public ConcurrentDictionary<string, WebSocket> GetAllSockets()
        {
        return _socket;
        
        }

        public string AddSocket(WebSocket socket) 
        {

            try
            {
                var ConnId = AbpSession.UserId.ToString(); //<==== Null

                    // Guid.NewGuid().ToString();


                //var test = AbpSession.UserId;


                _socket.TryAdd(ConnId/*dictionary item key*/, socket/*dictionary item value*/);
                Debug.WriteLine("Connection Added:"   ConnId);
                return ConnId;
            }
            catch(Exception ex)
            {
                throw new Exception(ex.Message);
            }
            
        }
}

Update 1:

And here is the client-side WebSocket initialization:


    async ngOnInit() {
this.connectWebSocket();

}

connectWebSocket(){
 
  this.socket=new WebSocket(this.webSocketUrl);

  this.socket.onopen=(event)=>{

  }

  this.socket.onclose=(event)=>{

  }


this.socket.onmessage=(event)=>{
this.isConnID(event.data);



  }

}

Update 2: Update3:

I have this in AuthConfigurer:

     /* This method is needed to authorize SignalR javascript client.
         * SignalR can not send authorization header. So, we are getting it from query string as an encrypted text. */
        private static Task QueryStringTokenResolver(MessageReceivedContext context)
        {

            var test = context.HttpContext.Request.Path.Value;//the value is null
            if (!context.HttpContext.Request.Path.HasValue ||
                (!context.HttpContext.Request.Path.Value.StartsWith("/signalr") && !context.HttpContext.Request.Path.Value.StartsWith("/ws")))
            {
                // We are just looking for signalr clients
                return Task.CompletedTask;
            }

            var qsAuthToken = context.HttpContext.Request.Query["enc_auth_token"].FirstOrDefault();
            if (qsAuthToken == null)
            {
                // Cookie value does not matches to querystring value
                return Task.CompletedTask;
            }

            // Set auth token from cookie
            context.Token = SimpleStringCipher.Instance.Decrypt(qsAuthToken, AppConsts.DefaultPassPhrase);
            return Task.CompletedTask;
        }

and in appsettings.json the Authentication section :


 "Authentication": {
    "JwtBearer": {
      "IsEnabled": "true",
      "SecurityKey": "Test_C421AAEE0D114E9C",
      "Issuer": "Test",
      "Audience": "Test"
    }
  },

CodePudding user response:

You need to pass authentication information.

  1. If you're using the ASP.NET Boilerplate Angular template (with Module Zero), you may pass enc_auth_token in the query string, which will be resolved by QueryStringTokenResolver.
// import { AppConsts } from '@shared/AppConsts';
// import { UtilsService } from 'abp-ng2-module';

connectWebSocket(){
    // this.socket=new WebSocket(this.webSocketUrl); // Change this to the following
    const encryptedAuthToken = new UtilsService().getCookieValue(AppConsts.authorization.encryptedAuthTokenName);
    const webSocketUrl = this.webSocketUrl   '?enc_auth_token='   encodeURIComponent(encryptedAuthToken);
    this.socket = new WebSocket(webSocketUrl);

    ...
}

Reference: SignalRAspNetCoreHelper.ts

  1. If webSocketUrl doesn't start with /signalr, whitelist it in QueryStringTokenResolver:
private static Task QueryStringTokenResolver(MessageReceivedContext context)
{
    if (!context.HttpContext.Request.Path.HasValue ||
     // !context.HttpContext.Request.Path.Value.StartsWith("/signalr")) // Change this to the following
       (!context.HttpContext.Request.Path.Value.StartsWith("/signalr") && 
        !context.HttpContext.Request.Path.Value.StartsWith(webSocketUrl))
    {
        // ...
        return Task.CompletedTask;
    }

    ...
}

Remember to add the WebSockets middleware if you're using raw WebSockets.

  • Add app.UseWebSockets() before app.UseEndpoints(...) in Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
    ...

    app.UseWebSockets() // Add this

    app.UseEndpoints(...
    ...
}

References:

  • Related