Skip to content

Instantly share code, notes, and snippets.

@davetimmins
Created April 11, 2013 23:00
Show Gist options
  • Save davetimmins/5367900 to your computer and use it in GitHub Desktop.
Save davetimmins/5367900 to your computer and use it in GitHub Desktop.
ServiceStack OAuth provider to allow authentication against ArcGIS Online
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