asp.net web api - SignalR authentication with webAPI Bearer Token -
asp.net web api - SignalR authentication with webAPI Bearer Token -
+i used this solution implement token based authentication using asp.net web api 2, owin, , identity...which worked out excellently well. used other solution , implement signalr hubs authorization , authentication passing bearer token through connection string, seems either bearer token not going, or else wrong somewhere, why here seeking help...these codes... querystringbearerauthorizeattribute: class in charge of verification
using impauth.entities; using microsoft.aspnet.identity.entityframework; using microsoft.owin.security; using microsoft.owin.security.oauth; using system; using system.collections.generic; using system.linq; using system.security.claims; using system.threading.tasks; using system.web; namespace impauth.providers { using system.security.claims; using microsoft.aspnet.signalr; using microsoft.aspnet.signalr.hubs; using microsoft.aspnet.signalr.owin; public class querystringbearerauthorizeattribute : authorizeattribute { public override bool authorizehubconnection(hubdescriptor hubdescriptor, irequest request) { var token = request.querystring.get("bearer"); var authenticationticket = startup.authserveroptions.accesstokenformat.unprotect(token); if (authenticationticket == null || authenticationticket.identity == null || !authenticationticket.identity.isauthenticated) { homecoming false; } request.environment["server.user"] = new claimsprincipal(authenticationticket.identity); request.environment["server.username"] = authenticationticket.identity.name; request.gethttpcontext().user = new claimsprincipal(authenticationticket.identity); homecoming true; } public override bool authorizehubmethodinvocation(ihubincominginvokercontext hubincominginvokercontext, bool appliestomethod) { var connectionid = hubincominginvokercontext.hub.context.connectionid; // check authenticated user principal environment var environment = hubincominginvokercontext.hub.context.request.environment; var principal = environment["server.user"] claimsprincipal; if (principal != null && principal.identity != null && principal.identity.isauthenticated) { // create new hubcallercontext instance principal generated token // , replace current context in hubs can retrieve current user identity hubincominginvokercontext.hub.context = new hubcallercontext(new serverrequest(environment), connectionid); homecoming true; } homecoming false; } } }
and start class....
using impauth.providers; using microsoft.aspnet.signalr; using microsoft.owin; using microsoft.owin.cors; using microsoft.owin.security.facebook; using microsoft.owin.security.google; //using microsoft.owin.security.facebook; //using microsoft.owin.security.google; using microsoft.owin.security.oauth; using owin; using system; using system.collections.generic; using system.data.entity; using system.linq; using system.web; using system.web.http; [assembly: owinstartup(typeof(impauth.startup))] namespace impauth { public class startup { public static oauthauthorizationserveroptions authserveroptions; static startup() { authserveroptions = new oauthauthorizationserveroptions { allowinsecurehttp = true, tokenendpointpath = new pathstring("/token"), accesstokenexpiretimespan = timespan.fromminutes(30), provider = new simpleauthorizationserverprovider() // refreshtokenprovider = new simplerefreshtokenprovider() }; } public static oauthbearerauthenticationoptions oauthbeareroptions { get; private set; } public static googleoauth2authenticationoptions googleauthoptions { get; private set; } public static facebookauthenticationoptions facebookauthoptions { get; private set; } public void configuration(iappbuilder app) { //app.mapsignalr(); configureoauth(app); app.map("/signalr", map => { // setup cors middleware run before signalr. // default allow origins. can // configure set of origins and/or http verbs // providing cors options different policy. map.usecors(corsoptions.allowall); var hubconfiguration = new hubconfiguration { // can enable jsonp uncommenting line below. // jsonp requests insecure older browsers (and // versions of ie) require jsonp work cross domain //enablejsonp = true enabledetailederrors = true }; // run signalr pipeline. we're not using mapsignalr // since branch runs under "/signalr" // path. map.runsignalr(hubconfiguration); }); httpconfiguration config = new httpconfiguration(); app.usecors(microsoft.owin.cors.corsoptions.allowall); webapiconfig.register(config); app.usewebapi(config); } public void configureoauth(iappbuilder app) { //use cookie temporarily store info user logging in 3rd party login provider app.useexternalsignincookie(microsoft.aspnet.identity.defaultauthenticationtypes.externalcookie); oauthbeareroptions = new oauthbearerauthenticationoptions(); oauthauthorizationserveroptions oauthserveroptions = new oauthauthorizationserveroptions() { allowinsecurehttp = true, tokenendpointpath = new pathstring("/token"), accesstokenexpiretimespan = timespan.fromdays(1), provider = new simpleauthorizationserverprovider() }; // token generation app.useoauthauthorizationserver(oauthserveroptions); app.useoauthbearerauthentication(new oauthbearerauthenticationoptions()); //configure google external login googleauthoptions = new googleoauth2authenticationoptions() { clientid = "1062903283154-94kdm6orqj8epcq3ilp4ep2liv96c5mn.apps.googleusercontent.com", clientsecret = "rv5mjuz0epwxmvwuaqjspp85", provider = new googleauthprovider() }; app.usegoogleauthentication(googleauthoptions); //configure facebook external login facebookauthoptions = new facebookauthenticationoptions() { appid = "charlie", appsecret = "xxxxxx", provider = new facebookauthprovider() }; app.usefacebookauthentication(facebookauthoptions); } } }
and knockout plus jquery code on client....
function chat(name, message) { self.name = ko.observable(name); self.message = ko.observable(message); } function viewmodel() { var self = this; self.chatmessages = ko.observablearray(); self.sendmessage = function () { if (!$('#message').val() == '' && !$('#name').val() == '') { $.connection.hub.qs = { bearer: "yych391w-cksvmv7ieh2queihduopwymxi12vh7gtnzjpwrrkajqgzhru5dnevkoy-hplj4myhznrb_emhm0fjrlx5bjmikhl6eeyjpmlwkrdm2lfgkmf4e82uaug1zfc7jfat4dfvhrshx9ay0zicnuwglvvyhiriew2v-f7d0bc18q5oqwzcmsogg2osr63gaax1oo9zojx5pe2clfhtlr7glcem6ctr0jz2myjsi" }; $.connection.hub.start().done(function () { $.connection.hub.qs = { bearer: "yych391w-cksvmv7ieh2queihduopwymxi12vh7gtnzjpwrrkajqgzhru5dnevkoy-hplj4myhznrb_emhm0fjrlx5bjmikhl6eeyjpmlwkrdm2lfgkmf4e82uaug1zfc7jfat4dfvhrshx9ay0zicnuwglvvyhiriew2v-f7d0bc18q5oqwzcmsogg2osr63gaax1oo9zojx5pe2clfhtlr7glcem6ctr0jz2myjsi" }; $.connection.impauthhub.server.sendmessage($('#name').val(), $('#message').val()) .done(function () { $('#message').val(''); $('#name').val(''); }) .fail(function (e) { alert(e) }); }); } } $.connection.impauthhub.client.newmessage = function (name, message) { //alert(ko.tojson(name, message)); var chat1 = new chat(name, message); self.chatmessages.push(chat1); } } ko.applybindings(new viewmodel());
and here hub class...
using impauth.providers; using microsoft.aspnet.signalr; using system; using system.collections.generic; using system.linq; using system.web; namespace impauth { public class impauthhub : hub { [querystringbearerauthorize] public void sendmessage(string name, string message) { clients.all.newmessage(name, message); } } }
...now problem comes when seek invoke authenticated hub class , error
caller not authenticated invove method sendmessage in impauthhub
but alter method in querystringbearerauthorizeattribute class alway homecoming true this
public override bool authorizehubmethodinvocation(ihubincominginvokercontext hubincominginvokercontext, bool appliestomethod) { var connectionid = hubincominginvokercontext.hub.context.connectionid; // check authenticated user principal environment var environment = hubincominginvokercontext.hub.context.request.environment; var principal = environment["server.user"] claimsprincipal; if (principal != null && principal.identity != null && principal.identity.isauthenticated) { // create new hubcallercontext instance principal generated token // , replace current context in hubs can retrieve current user identity hubincominginvokercontext.hub.context = new hubcallercontext(new serverrequest(environment), connectionid); homecoming true; } homecoming true; }
...it works....what problem code or implementation?
you need configure signalr this;
app.map("/signalr", map => { map.usecors(corsoptions.allowall); map.useoauthbearerauthentication(new oauthbearerauthenticationoptions() { provider = new querystringoauthbearerprovider() }); var hubconfiguration = new hubconfiguration { resolver = globalhost.dependencyresolver, }; map.runsignalr(hubconfiguration); });
then need write basic custom oauthbearerauthenticationprovider signalr accepts access_token query string.
public class querystringoauthbearerprovider : oauthbearerauthenticationprovider { public override task requesttoken(oauthrequesttokencontext context) { var value = context.request.query.get("access_token"); if (!string.isnullorempty(value)) { context.token = value; } homecoming task.fromresult<object>(null); } }
after need send access_token signalr connection querystring.
$.connection.hub.qs = { 'access_token': token };
and hub ordinary [authorize] attribute
public class impauthhub : hub { [authorize] public void sendmessage(string name, string message) { clients.all.newmessage(name, message); } }
hope helps. yd.
authentication asp.net-web-api token signalr.client
Comments
Post a Comment