c# - SignalR: Receive Custom Id on Every Call Including OnConnected -


i using signalr relay messages webapi server back-end javascript web page. these messages relayed users need map signalr connectionid custom id of user of webpage.

currently webapi uses formsauthentication , custom id need in cookie.

initially inherited iuseridprovider pull value off of cookie:

public class customidprovider : iuseridprovider {     public string getuserid(irequest request)     {         cookie formsauthcookie = request.cookies[formsauthentication.formscookiename];          try         {             formsauthenticationticket ticket = formsauthentication.decrypt(formsauthcookie.value);              var obj = jsonconvert.deserializeobject(ticket.name) jobject;              return (string)obj.getvalue("userid");         }         catch (exception)         {             return null;         }     } } 

which worked far getting custom id correctly. value never set on identity far tell. unable edit of identity values due context.user.identity.name being readonly.

edit: trying customidprovider again, correctly value out of cookie on returning getuserid method, onconnected never called.

my next approach based off of shaun xu's blogpost set context user principal customized authentication in signalr. here implementation:

public class customauthorizeattribute : authorizeattribute {     private const string custom_identity_key = "server.user";      public override bool authorizehubconnection(hubdescriptor hubdescriptor, irequest request)     {         string customid;          // gets custom id cookie.         trygetcustomid(request, out customid);          // customidentity class sets customid name.              request.environment.add(custom_identity_key, new claimsprincipal(new customidentity(customid, true)));          return true;     }      public override bool authorizehubmethodinvocation(ihubincominginvokercontext hubincominginvokercontext, bool appliestomethod)     {         string connectionid = hubincominginvokercontext.hub.context.connectionid;          idictionary<string, object> environment = hubincominginvokercontext.hub.context.request.environment;          object obj;          environment.trygetvalue(custom_identity_key, out obj);          var principal = obj claimsprincipal;          if (principal?.identity == null || !principal.identity.isauthenticated)         {             return false;         }          hubincominginvokercontext.hub.context = new hubcallercontext(new serverrequest(environment), connectionid);          return true;     } 

and works set context.user.identity correctly when both methods invoked.

however, problem when user first connects , onconnected called, not call authorizehubmethodinvocation , therefore context.user.identity not available in onconnected.

i want able access correct identity containing custom id @ stages of signalr hub: onconnected, ondisconnected, , invoked methods.

does have solution this?

i have comments:

1) should not try establish custom identity in authorization stage. should concern of authentication stage.

2) implementing custom iuseridprovider , establishing custom identity id of context.user.identity separate concerns. custom iuseridprovider map of properties of context.user.identity identifier of user in signalr.

so, fix problem. try establishing custom identity id @ authentication stage. there many ways depending on how setup application. example:

1) establishing custom identity id in application_postauthenticaterequest:

protected void application_postauthenticaterequest(object sender, eventargs e) {      //provide custom identity id httpcontext.current.user      //in case, may extract information authentication ticket. } 

you @ post if need detailed information: asp.net mvc - set custom iidentity or iprincipal

2) using claims identity, can return custom id claim, everytime when browser sends request server, claims identity re-established. in example below, use owin cookie authentication.

  var claims = new list<claim>();   claims.add(new claim(claimtypes.name, user.id.tostring()));    var id = new claimsidentity(claims, "cookies");   var ctx = request.getowincontext();   var authenticationmanager = ctx.authentication;   authenticationmanager.signin(id); 

then in iuseridprovider implementation, can extract corresponding information in identity (name property, claim,...) use user identifier in signalr application.


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo