Created
April 11, 2013 23:00
-
-
Save davetimmins/5367900 to your computer and use it in GitHub Desktop.
ServiceStack OAuth provider to allow authentication against ArcGIS Online
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ServiceStack.Configuration; | |
using ServiceStack.ServiceHost; | |
using ServiceStack.ServiceInterface; | |
using ServiceStack.ServiceInterface.Auth; | |
using ServiceStack.Common; | |
using ServiceStack.Text; | |
using System; | |
using System.Collections.Generic; | |
public class ArcGISAuthProvider : OAuthProvider | |
{ | |
public const string Name = "arcgis"; | |
public static string Realm = "https://www.arcgis.com/sharing/oauth2/"; | |
public ArcGISAuthProvider(IResourceManager appSettings) | |
: base(appSettings, Realm, Name) { } | |
public override object Authenticate(IServiceBase authService, IAuthSession session, ServiceStack.ServiceInterface.Auth.Auth request) | |
{ | |
var tokens = Init(authService, ref session, request); | |
var error = authService.RequestContext.Get<IHttpRequest>().QueryString["error"]; | |
var isPreAuthError = !error.IsNullOrEmpty(); | |
if (isPreAuthError) return authService.Redirect(session.ReferrerUrl); | |
var code = authService.RequestContext.Get<IHttpRequest>().QueryString["code"]; | |
var isPreAuthCallback = !code.IsNullOrEmpty(); | |
if (!isPreAuthCallback) | |
{ | |
var preAuthUrl = Realm + "authorize?response_type=code&client_id={0}&redirect_uri={1}"; | |
preAuthUrl = preAuthUrl.Fmt(ConsumerKey, CallbackUrl.UrlEncode()); | |
authService.SaveSession(session, SessionExpiry); | |
return authService.Redirect(preAuthUrl); | |
} | |
var accessTokenUrl = Realm + | |
"token?grant_type=authorization_code&code={0}&redirect_uri={1}&client_id={2}&client_secret={3}"; | |
accessTokenUrl = accessTokenUrl.Fmt(code, CallbackUrl.UrlEncode(), ConsumerKey, ConsumerSecret); | |
// get the access token and store the result | |
var contents = accessTokenUrl.GetStringFromUrl(); | |
var authInfo = JsonObject.Parse(contents); | |
tokens.AccessToken = authInfo["access_token"]; | |
if (tokens.AccessToken.IsNullOrEmpty()) | |
return authService.Redirect(session.ReferrerUrl.AddHashParam("f", "AccessTokenFailed")); | |
tokens.RefreshToken = authInfo["refresh_token"]; | |
tokens.RefreshTokenExpiry = DateTime.UtcNow.AddSeconds(Double.Parse(authInfo["expires_in"])); | |
tokens.UserName = authInfo["username"]; | |
session.IsAuthenticated = true; | |
OnAuthenticated(authService, session, tokens, authInfo.ToDictionary()); | |
authService.SaveSession(session, SessionExpiry); | |
return authService.Redirect(session.ReferrerUrl.AddHashParam("s", "1")); | |
} | |
protected override void LoadUserAuthInfo(AuthUserSession userSession, IOAuthTokens tokens, Dictionary<string, string> authInfo) | |
{ | |
var url = "https://www.arcgis.com/sharing/rest/community/users/{0}?f=json"; | |
url = url.Fmt(authInfo["username"]); | |
var json = url.GetStringFromUrl(); | |
var data = JsonObject.Parse(json); | |
tokens.DisplayName = data.Get("fullName"); | |
tokens.FullName = data.Get("fullName"); | |
// todo : get more data if available | |
} | |
public override void LoadUserOAuthProvider(IAuthSession authSession, IOAuthTokens tokens) | |
{ | |
var userSession = authSession as AuthUserSession; | |
if (userSession == null) return; | |
userSession.DisplayName = tokens.DisplayName ?? userSession.DisplayName; | |
userSession.FullName = tokens.FullName ?? userSession.DisplayName; | |
userSession.FirstName = tokens.FirstName ?? userSession.FirstName; | |
userSession.LastName = tokens.LastName ?? userSession.LastName; | |
userSession.PrimaryEmail = tokens.Email ?? userSession.PrimaryEmail ?? userSession.Email; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment