asp.net - How to let users login to my site using SoundCloud -



asp.net - How to let users login to my site using SoundCloud -

i want allow users authenticate via soundcloud asp.net mvc 4 project. since there no .net sdk, wrote custom oauth2client handle authentication. after adding client authconfig.cs, appropriately showed alternative login. problem is, when click on button login, returns

login failure. unsuccessful login service.

without asking me login in soundcloud. problem? implemented similar client github , worked no problems.

here client:

public class soundcloudoauth2client : oauth2client { private const string enduserauthlink = "https://soundcloud.com/connect"; private const string tokenlink = "https://api.soundcloud.com/oauth2/token"; private readonly string _clientid; private readonly string _clientsecret; public soundcloudoauth2client(string clientid, string clientsecret) : base("soundcloud") { if (string.isnullorwhitespace(clientid)) { throw new argumentnullexception("clientid"); } if (string.isnullorwhitespace(clientsecret)) { throw new argumentnullexception("clientsecret"); } _clientid = clientid; _clientsecret = clientsecret; } protected override uri getserviceloginurl(uri returnurl) { stringbuilder serviceurl = new stringbuilder(); serviceurl.append(enduserauthlink); serviceurl.appendformat("?client_id={0}", _clientid); serviceurl.appendformat("&response_type={0}", "code"); serviceurl.appendformat("&scope={0}", "non-expiring"); serviceurl.appendformat("&redirect_uri={0}", system.uri.escapedatastring(returnurl.tostring())); homecoming new uri(serviceurl.tostring()); } public override void requestauthentication(httpcontextbase context, uri returnurl) { base.requestauthentication(context, returnurl); } protected override idictionary<string, string> getuserdata(string accesstoken) { idictionary<string, string> extradata = new dictionary<string, string>(); var webrequest = (httpwebrequest)webrequest.create("https://api.soundcloud.com/me.json?oauth_token=" + accesstoken); webrequest.method = "get"; string response = ""; using (httpwebresponse webresponse = httpwebresponse)webrequest.getresponse()) { using (streamreader reader = new streamreader(webresponse.getresponsestream())) { response = reader.readtoend(); } } var json = jobject.parse(response); string id = (string)json["id"]; string username = (string)json["username"]; string permalinkurl = (string)json["permalink_url"]; extradata = new dictionary<string, string> { {"scaccesstoken", accesstoken}, {"username", username}, {"permalinkurl", permalinkurl}, {"id", id} }; homecoming extradata; } protected override string queryaccesstoken(uri returnurl, string authorizationcode) { stringbuilder postdata = new stringbuilder(); postdata.appendformat("client_id={0}", this._clientid); postdata.appendformat("&redirect_uri={0}", httputility.urlencode(returnurl.tostring())); postdata.appendformat("&client_secret={0}", this._clientsecret); postdata.appendformat("&grant_type={0}", "authorization_code"); postdata.appendformat("&code={0}", authorizationcode); string response = ""; string accesstoken = ""; var webrequest = (httpwebrequest)webrequest.create(tokenlink); webrequest.method = "post"; webrequest.contenttype = "application/x-www-form-urlencoded"; using (stream s = webrequest.getrequeststream()) { using (streamwriter sw = new streamwriter(s)) sw.write(postdata.tostring()); } using (webresponse webresponse = webrequest.getresponse()) { using (streamreader reader = new streamreader(webresponse.getresponsestream())) { response = reader.readtoend(); } } var json = jobject.parse(response); accesstoken = (string)json["access_token"]; homecoming accesstoken; } public override authenticationresult verifyauthentication(httpcontextbase context, uri returnpageurl) { string code = context.request.querystring["code"]; string u = context.request.url.tostring(); if (string.isnullorempty(code)) { homecoming authenticationresult.failed; } string accesstoken = this.queryaccesstoken(returnpageurl, code); if (accesstoken == null) { homecoming authenticationresult.failed; } idictionary<string, string> userdata = this.getuserdata(accesstoken); if (userdata == null) { homecoming authenticationresult.failed; } string id = userdata["id"]; string name; if (!userdata.trygetvalue("username", out name) && !userdata.trygetvalue("name", out name)) { name = id; } homecoming new authenticationresult( issuccessful: true, provider: "soundcloud", provideruserid: id, username: name, extradata: userdata); } }

and authconfig.cs:

public static void registerauth() { oauthwebsecurity.registerclient(new soundcloudoauth2client( clientid: myvalues.myclientid, clientsecret: myvalues.myclientsecret), displayname: "soundcloud", extradata: null); oauthwebsecurity.registerclient(new githuboauth2client( appid: myvalues.githubappid, appsecret: myvalues.githubappsecret), "github", null); oauthwebsecurity.registergoogleclient(); oauthwebsecurity.registeryahooclient(); }

there multiple issues address, starting first function runs: getserviceloginurl(uri returnurl)

the returnurl, automatically created, contains ampersands, soundcloud not like. need strip out ampersands , ensure "redirect uri authentication" in soundcloud business relationship exactly matches beingness sent (querystring , all). here illustration of beingness sent returnurl default:

https://localhost:44301/account/externallogincallback?__provider__=soundcloud&__sid__=blahblahyoursid

first step remove &__sid__ value. can strip out sid value , pass state parameter, in case ever need it. new function looks this:

protected override uri getserviceloginurl(uri returnurl) { stringbuilder serviceurl = new stringbuilder(); string sid = string.empty; if (returnurl.tostring().contains("__sid__")) { int index = returnurl.tostring().indexof("__sid__") + 8; int len = returnurl.tostring().length; sid = returnurl.tostring().substring(index, len - index-1); } string redirecturi = returnurl.tostring().contains('&') ? returnurl.tostring().substring(0,returnurl.tostring().indexof("&")) : returnurl.tostring(); serviceurl.append(enduserauthlink); serviceurl.appendformat("?client_id={0}", _clientid); serviceurl.appendformat("&response_type={0}", "code"); serviceurl.appendformat("&scope={0}", "non-expiring"); serviceurl.appendformat("&state={0}", sid); serviceurl.appendformat("&redirect_uri={0}", system.uri.escapedatastring(redirecturi)); homecoming new uri(serviceurl.tostring()); }

that solves part of problem. redirect uri in soundlcoud https://localhost:44301/account/externallogincallback?__provider__=soundcloud). trying authenticate still homecoming false. next issue address in accountcontroller.cs, specifically:

[allowanonymous] public actionresult externallogincallback(string returnurl)

because in first line, tries return:

authenticationresult result = oauthwebsecurity.verifyauthentication(url.action("externallogincallback", new { returnurl = returnurl }));

and doesn't run custom oauth2client, since verifyauthentication takes different parameters. prepare detecting if soundcloud client , utilize custom verifyauthentication:

[allowanonymous] public actionresult externallogincallback(string returnurl) { authenticationresult result; var context = this.httpcontext; string p = tools.getprovidernamefromquerystring(context.request.querystring); if (!string.isnullorempty(p) && p.tolower() == "soundcloud") { result = new soundcloudoauth2client( clientid: myvalues.scclientid, clientsecret: myvalues.scclientsecret).verifyauthentication(this.httpcontext, new uri(string.format("{0}/account/externallogincallback?__provider__=soundcloud", context.request.url.getleftpart(uripartial.authority).tostring()))); } else { result = oauthwebsecurity.verifyauthentication(url.action("externallogincallback", new { returnurl = returnurl })); }

where

public static string getprovidernamefromquerystring(namevaluecollection querystring) { var result = querystring["__provider__"]; ///commented out stuff homecoming result; }

after that, works fine , can authenticate. can configure getuserdata whatever soundcloud info want save , save off userprofile or related table. key part scaccesstoken because need in future upload account.

asp.net asp.net-mvc-4 asp.net-membership oauth-2.0 soundcloud

Comments

Popular posts from this blog

javascript - mongodb won't find my schema method in nested container -

How do you set up a perforce server to work over the internet? -

ios - Lagging ScrollView with UIWebview inside -