Zulfiqar's weblog

Architecture, security & random .Net

Archive for the ‘Azure AD’ Category

Federating Azure AD with thinktecture Identity Server – Notes

Posted by zamd on February 6, 2015

First of all my apologies for not doing a good job here. I always planned to contribute this to the excellent identity server  but I never got enough bandwidth to do so. I’m constantly receiving request to share the details here so I decided to share notes/steps required to enable this and hopefully someone from community would do the bits I have long promised.

Here are steps…

  1. Create a basic STS or tweak & use the lovely thinktecture IdentityServer v2 (my recommendation)
  2. Within identity server, add a Relying Party Trust to ‘urn:federation:MicrosoftOnline’ which is the unique identifier used by of Azure AD for federation.
  3. Establish a trust relationship between identity server and Azure AD using the Set-MsolDomainAuthentication cmdlet. This is how my trust relationship look like:

Office365 Federation Working

4. The IssuerUri MUST match the issuer URI of SAML assertion.

assertion-azure-ad-fed

 

5. The protocol MSUT be WS-Federation for browser-based SSO

6. Following claims MUST be included in the issued tokens

7. The UPN must also be set as a name identifier.

Identity server code change # 1


var nameid = new Claim(ClaimTypes.NameIdentifier, “7960192”);
nameid.Properties[ClaimProperties.SamlNameIdentifierFormat] = “urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified”;
var outputClaims = new List<Claim> {

new Claim(“http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID”,”7960192″),
new Claim(“http://schemas.xmlsoap.org/claims/UPN”, “zulfiqar@bccoss.com”),
nameid
};

 


 

 

8. The signing algorithm MUST be SHA-1. Signing certificate can be a self-signed SSL certificate.

Identity server code change # 2


scope.SigningCredentials = new X509SigningCredentials(signingCert, SecurityAlgorithms.RsaSha1Signature, SecurityAlgorithms.Sha1Digest);


 

9. The token MUST be sent to: https://login.microsoftonline.com/login.srf

Looking forward to see this in identity server soon…

Posted in Azure AD, Federation/STS, Office 365, SSO, Windows Azure | Tagged: | Leave a Comment »

Azure AD OAuth 2.0 Authorization Grant

Posted by zamd on May 17, 2013

Yesterday I talked about a bug which prevented me to complete the authorization grant flow with Azure AD. It turn out the bug is only exposed when using Azure Management Portal for Relying party registration. In this post, I’ll use Graph Explorer to do the registration which works fine.

My scenario is to create a simple MVC application which would do the user authentication against the Azure AD.

Once the user is signed in, the web app then acquires an “access” & “refresh token” for the Graph API (I’ll work with other resources in future) using the 3-leg authorization grant flow.

I started by creating an empty MVC 4.0 application and added a home controller with a simple view displaying the identity & claims of the authenticated user.

image

Running the app gave me the url which I would use to register my app with Azure AD using Graph Explorer.  Registration instruction are available in this blog post under the ‘Setting up permissions’ section. My registration settings looks like this

image

Now back to VS and using the “Identity & Access”, I have externalized the authentication of my app to windows azure AD.

image

The tooling does all the magic and generates required WIF configuration.

<system.identityModel>
<identityConfiguration>
<audienceUris>
<addvalue=http://localhost:45906/ />
</audienceUris>
<issuerNameRegistrytype=System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089>
<trustedIssuers>
<addthumbprint=3464C5BDD2BE7F2B6112E2F08E9C0024E33D9FE0name=https://sts.windows.net/{tenantid}/ />
</trustedIssuers>
</issuerNameRegistry>
<certificateValidationcertificateValidationMode=None/>
</identityConfiguration>
</system.identityModel>
<system.identityModel.services>
<federationConfiguration>
<cookieHandlerrequireSsl=false />
<wsFederationpassiveRedirectEnabled=trueissuer=https://login.windows.net/common/wsfedrealm=http://localhost:45906/reply=http://localhost:45906/requireHttps=false />
</federationConfiguration>
</system.identityModel.services>

Now when I run my application, I’m redirected to azure AD for authentication and after signing in, I’m back in my app with following claims.

image

The Authorize action simply redirects to the authorization endpoint requesting an ‘authorization code’.

Acquire authorization code
publicActionResult Authorize()
{
var @params = newNameValueCollection
{
{“response_type”, “code”},
{“client_id”, “87638e3d-6b56-46b6-946f-8b3b9fa6f04e”},
{“resource”, https://graph.windows.net&#8221;},
{“redirect_uri”, Url.Action(“Authorized”, null, null, “http”)}
};
var query = HttpUtility.ParseQueryString(“”);
query.Add(@params);    return Redirect(Constants.AzureADAuthorizationEndpoint + “?” + query);
}

 

I’m passing Authorized action as the redirect_uri to Azure AD. That’s where AD would send me the ‘authorization code’.

Clicking the ‘Authorize’ link takes me to Azure Ad & after authentication AD redirects my browser back to Authorized action with an authorization code.

http://localhost:45906/Home/Authorized?code=AAAAAAAAcJ3MFRmxlJAB5CwTBrXmI7t8zdfTrUmfPCbGHQCxbWXOxLieUD4r_fah-rnOwQkxS6B_KOSdLhjsf6n5sQghMwu9ynqFD2-qHBfRkxE3DnS8htlHaDqCdG-Wa5MvbRXZeCKUFr-k37n5Mn4T2KCdKx-nkyNheqZJmwmDFWwix_Gi_QJohhUMk-SDyrnV4Jy-tT_gfiKwKRzVi31JmsJV_b8u-5p398GsGfxBlfxuWuNYuUiUOUDdfLQCYbK0urn0HChsndnPuTZJxtJtNH7WdWnUdha108kVctvHW4u8IihV9P10OsM1gT_D67f00SjVIAA

From the Authorized controller action I fire a post request which gives me access and refresh tokens back. Please note, the redirect_uri MUST be same for both authorization code and token request.

Exchange code with tokens
publicasyncTask<ActionResult> Authorized(string code)
{
if (string.IsNullOrEmpty(code))
RedirectToAction(“Index”);    var data = newDictionary<string, string>
{
{“grant_type”, “authorization_code”},
{“client_id”, “87638e3d-6b56-46b6-946f-8b3b9fa6f04e”},
{“redirect_uri”, Url.Action(“Authorized”, null, null, “http”)},
{“client_secret”, “V/7FTVm****************UQi6MkbwhmBqKxz0=”},
{“code”, code}
};

var client = newHttpClient(newWebRequestHandler());
var response = await client.PostAsync(Constants.AzureADTokenEndpoint, newFormUrlEncodedContent(data));
response.EnsureSuccessStatusCode();

var msg = await response.Content.ReadAsStringAsync();
var tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(msg);
return View(tokenResponse);
}

image

The access & refresh tokens are scoped to Graph API in this case. I can now attach this “access token” to my requests to graph API to read/write the directory data. There are few samples on this topic already so I’m not going to cover that in this post.

Source: HomeController.cs

Posted in Azure AD, OAuth 2.0 | Leave a Comment »

Azure AD OAuth 2.0 Client_Credentials Flow

Posted by zamd on May 16, 2013

I was playing with the Authorization code grant type recently added to Azure Active directory however there is bug in the preview implementation which prevents exchange an ‘authorization code’ with an access token.

I can get the authorization code for graph api by using following url in the browser.

https://login.windows.net/69383356-56dd-4e78-a18e-a4ff5450c995/oauth2/authorize?response_type=code&client_id=9f030b74-1ec1-4b6b-8911-f4e6e465ff9d&resource=https://graph.windows.net&api-version=1.0

AAD authenticates me and redirects with an authorization code below.

http://localhost/?code=AAAAAAAAfgMZDe1KgG-yqkz7_upts_gtuQ5RgzoM71bkz3PKJo312flYTAp8PrpaUnl3nMaRF_asmQnEZpMjQSflFRJoFl0nVO5HyGnyRG2haLQAM7kz0wrW3I_D2s5FResTcc2g3hnStrVLWFoAovnw6gjh7Imir3Zistm7ZuJgFkbzMJp8Q1Nm1ZCoqW8W9lDDZtdizd9uI6ALo04OW9jp4bjW9KXshy2x6Nz41N35RzXD2DGiAJP5PqtCB1q54wmRsMauPtKrBxU7Nd3T3cbUV5XJxdNojZWaz-ER-tWYySVNMwLZ0gcRzIp-FMWy3Y7oGsHEpAWrrpmnV3Nx6K2Wb_BIXW-EI6HAQX57HDCFVmhBR8cgAA

At this stage, I should be able to exchange this ‘code’ with an ‘access token’ & a refresh token by issuing following POST request via fiddler.

‘https://login.windows.net/69383356-56dd-4e78-a18e-a4ff5450c995/oauth2/token

User-Agent: Fiddler

Content-Type: application/x-www-form-urlencoded

Host: login.windows.net

Content-Length: 546

grant_type=authorization_code&client_id=9f030b74-1ec1-4b6b-8911-f4e6e465ff9d&redirect_uri=http://localhost/&code=AAAAAAAAU1SjeRieJ2c2QVOayghJbBw-kihXTp7BrG10v73WsqEzFVgsgm3SfYv64_mT9WXFU02vvoVY8J7AxuAfcbJ9fysCW3TI3zixbrwPoz2rZruWJVMT5J7XSI34nxRA13kXIvwf8Sbv7EALsJw-2V56jCFz1sXNwQkkw7UBWX72qvlCP6CuhX0Rqw6LI_4Uqh5dk9D6MLNk02ttTyKnrMkFqV0eN96DhuYZXYD_dF331of8_AULAvkGNGwQzCcqCpws57X8l2rmczkDjvXTAQD2yC6Pb_Hq7eBNNxvFHKTR0D9gquwmPsXVY_jDae2nOa7fI4JdNM92Nto0UFLVoVnIuhxGhhIQzxLz9qb_b-I6fnUgAA&client_secret=V62j8vqo4pRHpCSOK/+jSa1ww=+V62j8vqo4pRHpCSOK/+jSa1ww=

However doing this results in a ‘ACS50000: There was an error issuing a token. ACS70001: Error validating credentials. ACS50012: Invalid client secret is provided’ error. I’ll do a follow up post when this bug is fixed.

My second choice was to use the simple client_credentials (also known as two-leg) flow.

This time I used fiddler to craft a POST request to directly acquire a token from AAD OAuth 2.0 endpoint.

https://login.windows.net/69383356-56dd-4e78-a18e-a4ff5450c995/oauth2/token?api-version=1.0

User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: login.windows.net
Content-Length: 178

grant_type=client_credentials&client_id=9f030b74-1ec1-33s3-8911-f4e6e465ff9d&client_secret=V62j8vqo4pRHpCSOK/+jSa1ww=+V62j8vqo4pRHpCSOK/+jSa1ww=&resource=http%3A%2F%2Flocalhost%2F

image

I got 200 OK with JWT token as the payload. I can now attach this token to my REST services where I can process it using the WIF JWTTokenHandler extension as shown below:

  1. static void Main(string[] args)
  2. {
  3.     var handler = new JWTSecurityTokenHandler();
  4.     var token = (JWTSecurityToken)
  5.     handler.ReadToken(
  6.         "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwOi8vbG9jYWxob3N0LyIsImlzcyI6Imh0dHBzOi8vc3RzLndpbmRvd3MubmV0LzY5MzgzMzU2LTU2ZGQtNGU3OC1hMThlLWE0ZmY1NDUwYzk5NS8iLCJuYmYiOjEzNjg3Mzk2NTYsImV4cCI6MTM2ODc4Mjg1Niwic3ViIjoiY2MyMjQ1NTQtZDhlZC00YTY0LThmZjUtOTJiZjNiYjEzZDkyIiwiYXBwaWQiOiI5ZjAzMGI3NC0xZWMxLTRiNmItODkxMS1mNGU2ZTQ2NWZmOWQiLCJvaWQiOiJjYzIyNDU1NC1kOGVkLTRhNjQtOGZmNS05MmJmM2JiMTNkOTIiLCJ0aWQiOiI2OTM4MzM1Ni01NmRkLTRlNzgtYTE4ZS1hNGZmNTQ1MGM5OTUiLCJpZHAiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC82OTM4MzM1Ni01NmRkLTRlNzgtYTE4ZS1hNGZmNTQ1MGM5OTUvIn0.BLtqbzU5pEyn5c6ubQxu2UPzoCd_I9Rokycq4LqThWGkdAy9vL3vqptAHXlKOTK-VFPkarfJ1Jui-GaiGZE_BKLFW0x_cxv4bTx_fAktTsDK51iv9wD8jYuftrUWaaqoonD29SQxRmic_r38LBqJwQIJRO4IfMUeMLmgYQ7B1DQs24D9oSx36pyc7CzX3sZH-nfbNPF4z8wUHrX0zzf7KwWCu5RhK6wmXKbiNKaMIw3VzTq6KsEbqFBV-3IuGFSGadrUfpJG0KZrEc3ZhNJ_gEWuBwhwTKtaVrWQ3_1wyxTtdKG1dPuVZmFxKCIfOJkqsvTFZKD4bECv5DJfvyhzlQ");
  7.     var validationParams = new TokenValidationParameters
  8.                                {
  9.                                    AudienceUriMode = AudienceUriMode.Never,
  10.                                    SigningTokenResolver = new HardcodedCertResolver(),
  11.                                    ValidateIssuer = false
  12.                                };
  13.     var ci = handler.ValidateToken(token,validationParams);
  14.  
  15.     ci.Claims.ToList().ForEach(c =>
  16.                                Console.WriteLine("{0} = {1}", c.Type, c.Value));
  17.  
  18.     Console.WriteLine(token.ValidTo);
  19.     Console.ReadLine();
  20. }

 

Hope that helps.

Posted in Azure AD, OAuth 2.0 | Leave a Comment »

Federating Office 365 (Azure Active Directory) with a Custom STS

Posted by zamd on February 8, 2013

Let’s start of with a clarification: As of today, federating Office 365 (Azure AD) with a Custom STS is NOT supported by Microsoft.  Today the only supported STSs are AD FS 2.0, Shibboleth 2, Optimal IDM Federation Services and PingFederate 6.10.

With that cleared, Office 365 STS supports both WS-Federation & SAML protocols for user authentication which means technically any compatible STS can be used as the Identity Provider STS for Office 365 services or other Relying Parties with a trust relationship with Azure Active Directory.

Azure AD supports In-cloud & Federated Identities.

With In-Cloud identities all user information, including the passwords, are stored in the online directory.

With Federating identities, only basic information is stored in online directory (as shadow accounts) and user identities are mastered in on-premise directories. Passwords are never copied to online directory and Azure AD relies on federation for user sign in.

A key prerequisite for Office 365 SSO is to create federated identities (shadow accounts) in Azure AD and there are different options/tools to do this.

  1. DirSync is the recommended tool but it only supports Active Directory as the identity source. DirSync & AD FS 2.0 are the primary tools to enable federation between an on-premises AD and Azure AD.
  2. Graph API is a new RESTful API to manage online directory and looks very promising for creating cloud-only identities. Graph API today doesn’t support creating Federated identities.
  3. MSOL PowerShell cmdlets: These cmdlets use the SOAP based Provisioning Service and are functionally quite rich. They support most of the operations including the creation of federated identities. I have used these cmdlet for my scenairo. Few commerical tools also wrap these cmdlets to perform various Office 365 provisioning operations.
  4. Forfront Identity Manager (FIM) is another potential option which can create Federated accounts from source directories other than AD but I haven’t explored that in detail.

Now once you have the federated identities provisioned (or synced from your on-premises user identity store) in Azure AD, the next step is to establish a trust relationship between Azure AD and your custom STS. This is assuming you have already done the domain verification etc.

I have used Set-MsolDomainAuthentication cmdlet for this.

Set-MsolDomainAuthentication –DomainName bccoss.com –federationBrandName bccoss.com -Authentication Federated  -PassiveLogOnUri $url -SigningCertificate $certData -IssuerUri $uri -ActiveLogOnUri $ecpUrl -LogOffUri $logoutUrl -PreferredAuthenticationProtocol WSFed

image 

At this stage, if I browse to the Microsoft Online Services portal (http://portal.microsoftonline.com/) and choose to login using my federated domain (@bccoss.com) – I got redirected to my custom STS.

In this case, I’m using Thinktecture STS but that doesn’t work out of box with Office 365 / Azure AD so I have to modify the STS to make it compatible with Azure AD. I’ll explain the Office 365 compatibility requirements of an STS in a future post.

I’ll also try to contribute my Thinktecture modification to code back to git at some point.

image image

image image

image image

Posted in Azure AD, Office 365, SSO | 11 Comments »