Skip to content

Instantly share code, notes, and snippets.

@fubar-coder
Created November 19, 2014 14:46
Show Gist options
  • Save fubar-coder/1e169fb5062829b1620d to your computer and use it in GitHub Desktop.
Save fubar-coder/1e169fb5062829b1620d to your computer and use it in GitHub Desktop.
Prototype of Auzre AD OAuth2 client for RestSharp.Portable
using Newtonsoft.Json;
using RestSharp.Portable;
using RestSharp.Portable.Authenticators.OAuth2;
using RestSharp.Portable.Authenticators.OAuth2.Configuration;
using RestSharp.Portable.Authenticators.OAuth2.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestOAuthAD
{
class AzureAdSystemClient : OAuth2Client
{
private string _tenantId;
private Endpoint _accessCodeServiceEndpoint;
private Endpoint _accessTokenServiceEndpoint;
public AzureAdSystemClient(IRequestFactory factory, IClientConfiguration configuration, string tenantId = "common")
: base(factory, configuration)
{
_tenantId = tenantId;
}
public string TenantId { get { return _tenantId; } }
public string PrincipalName { get; private set; }
public string ObjectId { get; private set; }
protected override Endpoint AccessCodeServiceEndpoint
{
get
{
if (_accessCodeServiceEndpoint == null)
_accessCodeServiceEndpoint = new Endpoint
{
BaseUri = "https://login.windows.net/",
Resource = string.Format("{0}/oauth2/authorize", _tenantId),
};
return _accessCodeServiceEndpoint;
}
}
protected override Endpoint AccessTokenServiceEndpoint
{
get
{
if (_accessTokenServiceEndpoint == null)
_accessTokenServiceEndpoint = new Endpoint
{
BaseUri = "https://login.windows.net/",
Resource = string.Format("{0}/oauth2/token", _tenantId),
};
return _accessTokenServiceEndpoint;
}
}
public override string Name
{
get
{
return "AzureAD";
}
}
private static string FixBase64(string base64)
{
base64 = base64.Replace('-', '+').Replace('_', '/');
switch (base64.Length % 4)
{
case 2:
base64 += "==";
break;
case 3:
base64 += "=";
break;
}
return base64;
}
protected override void BeforeGetAccessToken(BeforeAfterRequestArgs args)
{
base.BeforeGetAccessToken(args);
var res = args.Parameters["resource"].SingleOrDefault();
if (!string.IsNullOrEmpty(res))
args.Request.AddParameter("resource", res);
}
protected override void AfterGetAccessToken(BeforeAfterRequestArgs args)
{
dynamic response = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(args.Response.RawBytes));
var tokenId = (string)response.id_token;
var parts = tokenId.Split('.');
var jwtRaw = FixBase64(parts[1]);
dynamic jwt = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Convert.FromBase64String(jwtRaw)));
string newTenantId = jwt.tid;
if (!string.IsNullOrEmpty(newTenantId))
_tenantId = newTenantId;
ObjectId = jwt.oid;
PrincipalName = jwt.upn;
base.AfterGetAccessToken(args);
}
protected override RestSharp.Portable.Authenticators.OAuth2.Models.UserInfo ParseUserInfo(string content)
{
throw new NotImplementedException();
}
protected override Endpoint UserInfoServiceEndpoint
{
get
{
throw new NotImplementedException();
}
}
}
}
@fubar-coder
Copy link
Author

Add a resource parameter with value "https://graph.windows.net/" to the GetToken function to get access to the user information using the graph API.
You can use the graph API with the following lines:

var svcRoot = string.Format("https://graph.windows.net/{0}/", _authClient.TenantId);
var client = new Microsoft.Azure.ActiveDirectory.GraphClient.ActiveDirectoryClient(new Uri(svcRoot), async () => await _authClient.GetCurrentToken());

You need at least RestSharp.Portable v1.8.4 for this to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment