<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Microsoft Azure Simplified</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/microsoft_azure_simplified/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/microsoft_azure_simplified/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 04:09:30 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Getting started - Using Azure Active Directory (AAD) for authenticating automated clients (C#)</title>
      <link>https://docs.microsoft.com/archive/blogs/microsoft_azure_simplified/getting-started-using-azure-active-directory-aad-for-authenticating-automated-clients-c</link>
      <pubDate>Sun, 22 Mar 2015 11:54:00 GMT</pubDate>
      <dc:creator><![CDATA[abhay.microsoft]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/microsoft_azure_simplified/2015/03/22/getting-started-using-azure-active-directory-aad-for-authenticating-automated-clients-c/</guid>
      <description><![CDATA[In this post, we will create an ASP.Net Web API as the service to be protected and a console...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;">In this post, we will create an ASP.Net Web API as the service to be protected and a console application as the automated client consuming the service. We will implement three methods for the client to authenticate itself to Azure AD to get the claims (Certificate, Key and Credential), that it will then send to the Web API along with service. The Web API will authenticate the client based on the claims received. We will be implementing both the Web API and the client from empty visual studio projects. For implementing this authentication scenario, you need not be the administrator of the Azure Active Directory tenant, but must be a user of it.</span></p>
<p><span style="font-size: small;">This post contains the following sections:</span></p>
<ol>
<li><strong>Registering Web API with Azure AD Tenant</strong></li>
<li><strong>Creating Web API</strong></li>
<li><strong>Registering Client with Azure AD Tenant&nbsp;</strong></li>
<li><strong>Creating client application</strong></li>
<li><strong>Getting client claims on the server (Web API) side</strong></li>
<li><strong>Removing certificate authentication for the client</strong></li>
<li><strong>Using Keys instead of certificate to authenticate client</strong></li>
<li><strong>Fetching Object ID for a certificate or key authenticated AD client</strong></li>
<li><strong>Using username and password instead of certificate/key authentication</strong></li>
<li><strong>Read more/ References<span><strong><strong><strong><span><strong><strong><span><strong><strong><span><strong><br /></strong></span></strong></strong></span></strong></strong></span></strong></strong></strong></span></strong></li>
</ol>
<p><span style="font-size: medium;"><strong>Prerequisites:</strong></span></p>
<ul>
<li><span style="font-size: small;">An Azure Active Directory tenant that you are a user of.&nbsp;</span></li>
</ul>
<p><span style="font-size: small;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;We will be using an AD named RisingVentureDirectory and a user in it with username as ajay@risingventure.onmicrosoft.com.</span></p>
<ul>
<li><span style="font-size: small;">Visual Studio 2013</span></li>
</ul>
<p><span style="text-decoration: underline;"><strong><span style="font-size: large;">1. Registering Web API with Azure AD Tenant</span></strong></span></p>
<p>&nbsp; 1.<span style="font-size: small;"> Log into Azure management <a title="portal" href="https://manage.windowsazure.com" target="_blank">portal</a>. Click on Active Directory in left navigation panel. Go to <span style="color: #000000;">APPLICATIONS</span> tab of your AD. Click on ADD at the bottom bar.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/6443.AddApplication.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/6443.AddApplication.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/6443.AddApplication.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/6443.AddApplication.png" alt="" border="0" /></a></p>
<p>&nbsp; <span style="font-size: small;">2. Click on 'Add an application my organization is developing'.</span></p>
<p><span style="font-size: small;">&nbsp; 3. Enter name of your application (ex. RisingWebAPI). Select 'WEB APPLICATION AND/OR WEB API'. Click next.</span></p>
<p><span style="font-size: small;">&nbsp; 4. In Sign-on URL, enter URL for the Web API. This does not have to be a working URL. It can be the base URL for the Web API assigned by Visual Studio (e.g. https://localhost:10000).&nbsp;</span></p>
<p><span style="font-size: small;">&nbsp; 5. In App ID URI, enter https://&lt;AD_Tenant_FullName&gt;/&lt;Name_Of_WebAPI&gt;. (e.g. https://risingventure.onmicrsoft.com/risingwebapi)</span></p>
<p><span style="font-size: small;">&nbsp; 6. Click OK mark to complete the registration.</span></p>
<p><span style="font-size: small;">&nbsp; 7. Go to CONFIGURE tab of the just registered application. Note the Client ID for it.</span></p>
<p><span style="text-decoration: underline; font-size: large;"><strong>2. Creating Web API</strong></span></p>
<p><span style="font-size: small;">&nbsp; 1. Create an ASP.Net project in Visual Studio and name it RisingWebAPI&nbsp;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/7823.CreateProject.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/7823.CreateProject.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/7823.CreateProject.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/7823.CreateProject.png" alt="" border="0" /></a>&nbsp;</p>
<p><span style="font-size: small;">&nbsp; 2. Select Empty template and check WebAPI option. Click on OK to create the Web API.</span></p>
<p>&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1462.template.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1462.template.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1462.template.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1462.template.png" alt="" border="0" /></a></p>
<p><span style="font-size: small;">&nbsp; 3. Open Web.config and add the following keys in App settings:</span></p>
<pre class="scroll"><code class="csharp">&lt;appSettings&gt;<br /> &lt;add key="Tenant" value="risingventure.onmicrosoft.com" /&gt;<br /> &lt;add key="Audience" value="https://risingventure.onmicrosoft.com/risingwebapi" /&gt;<br /> &lt;add key="ClientID" value="226c660b-fb73-46d5-99b2-c453b271a30d" /&gt;<br /> &lt;/appSettings&gt;</code></pre>
<pre><span style="font-size: small;">4. Install the following Nuget packages to the RisingWebAPI project :</span></pre>
<ul>
<li><span style="font-size: small;">Microsoft.Owin</span></li>
<li><span style="font-size: small;">Microsoft.Owin.Security.ActiveDirectory</span></li>
<li><span style="font-size: small;">Microsoft.Owin.Host.SystemWeb (This is for hosting the Web API in IIS/IIS express)</span></li>
</ul>
<p><span style="font-size: small;">&nbsp; 5. Add a C# file to the project, named Startup.cs and put the following content into it: &nbsp; &nbsp;</span> &nbsp; &nbsp;&nbsp;</p>
<pre class="scroll"><code class="csharp">using Owin;<br /> <br /> namespace RisingWebAPI<br /> {<br /> public partial class Startup<br /> {<br /> public void Configuration(IAppBuilder app)<br /> {<br /> ConfigureAuth(app);<br /> }<br /> }<br /> }</code></pre>
<p>&nbsp; &nbsp; <span style="font-size: small;">&nbsp;Please note the class must be named 'Startup'. This class is automatically found and initialized by the new ASP.Net runtime and its 'Configuration' method is called by passing IAppBuilder object. Note that this should be in default namespace of the Web API project. You can find the default namespace from project properties. If it is not in default namespace, you must add a key in 'AppSettings' section of Web.Config, like:&nbsp;<span>&lt;add key="owin:AppStartup" value="[Namespace].Startup" /&gt;.&nbsp;</span>&nbsp;If IAppBuilder interface is unrecognized in VS, re-install the Owin nuget package. We will add ConfigureAuth method next.</span></p>
<p>&nbsp;<span style="font-size: small;"> 6. Add another C# file to the folder App_Start in the Web API project and put the following content into it:&nbsp;</span></p>
<pre class="scroll"><code class="csharp">using System.Configuration;<br /> using Microsoft.Owin.Security.ActiveDirectory;<br /> using Owin;<br /> using System.IdentityModel.Tokens;<br /> <br /> namespace RisingWebAPI<br /> {<br /> public partial class Startup<br /> {<br /> public void ConfigureAuth(IAppBuilder app)<br /> {<br /> var tokenValidationParameter = new TokenValidationParameters();<br /> tokenValidationParameter.ValidAudience = ConfigurationManager.AppSettings["Audience"];<br /> app.UseWindowsAzureActiveDirectoryBearerAuthentication(<br /> new WindowsAzureActiveDirectoryBearerAuthenticationOptions<br /> {<br /> TokenValidationParameters = tokenValidationParameter,<br /> Tenant = ConfigurationManager.AppSettings["Tenant"]<br /> });<br /> }<br /> }<br /> }</code></pre>
<p>&nbsp;<span style="font-size: small;"> &nbsp;7. Add a controller named GetdataController to the Web API project. Select 'Web API 2 Controller - Empty' from Add Scaffold window. Put the following content in it:</span></p>
<pre class="scroll"><code class="csharp">using System.Web.Http;<br /> <br /> namespace RisingWebAPI.Controllers<br /> {<br /> [Authorize]<br /> public class GetdataController : ApiController<br /> {<br /> public string Get()<br /> {<br /> return "Hello";<br /> }<br /> }<br /> }</code></pre>
<p>&nbsp;<span style="font-size: small;"> 8. Save and build the solution. Run the solution by pressing F5. If you try to access the Getdata controller (for example by hitting https://localhost:10000/api/getdata from a browser), it will give authorization error. This is because the WebAPI is now configured for Azure AD authentication and we require the Getdata controller to be authenticated ([Authorize] attribute). If you add any other controller without [Authorize] attribute,&nbsp;it should still be accessible. Next we will create the client that will get the authentication token from Azure AD tenant and pass to Web API.</span></p>
<p>&nbsp;</p>
<p><span style="text-decoration: underline; font-size: large;"><strong>3. Registering Client with Azure AD Tenant&nbsp;</strong></span></p>
<p><span style="font-size: small;">Clients can authenticate to Azure AD tenant through three ways : certificate credential, client keys and username/password credential. In this section we will cover certificate credential. Other two would be discussed in later sections. Certificate and client keys create an application identity while username/password will have an identity of a user (whose credential is used to authenticate).</span></p>
<p><span style="font-size: small;">&nbsp; 1. Go to Azure AD tenant as mentioned earlier on Azure management portal.</span></p>
<p><span style="font-size: small;">&nbsp; 2. On the APPLICATIONS tab, click ADD from the bottom bar.</span></p>
<p><span style="font-size: small;">&nbsp; 3. Click on 'Add an application my organization is developing'.</span></p>
<p><span style="font-size: small;">&nbsp; 4. Enter meaningful name for the application (e.g. RisingAPIClient).</span></p>
<p><span style="font-size: small;">&nbsp; 5. Select 'WEB APPLICATION AND/OR WEB API'. It does not matter if our client application is a native console app. Go next.</span></p>
<p><span style="font-size: small;">&nbsp; 6. For Sign-on URL and App ID URI, enter any valid URI. (e.g. https://risingapiclient/ for both fields). This does not have to be an existing/working URL, however, App ID URI must be unique within your AD. Click OK mark to register the application.</span></p>
<p><span style="font-size: small;">&nbsp; 7. Go to the CONFIGURE tab of the just added application and copy the client ID. Also give the client application access to the Web API. In the CONFIGURE, scroll to the bottom and click on 'Add application'.&nbsp;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1680.permission1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1680.permission1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1680.permission1.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1680.permission1.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; <span style="font-size: small;">&nbsp; Select 'All Apps' from the drop down menu from the pop up window.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8713.permission2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8713.permission2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8713.permission2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8713.permission2.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp;<span style="font-size: small;"> &nbsp;Search for the 'RisingWebAPI' and select it. Click ok mark then.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8880.permission3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8880.permission3.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8880.permission3.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8880.permission3.png" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; <span style="font-size: small;">Give permission to 'Access RisingWebAPI' and click save.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/7774.permission4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/7774.permission4.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/7774.permission4.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/7774.permission4.png" alt="" border="0" /></a></p>
<p>&nbsp;<span style="font-size: small;"> 8. Run the following command to create a self-signed certificate on your computer from developer command prompt:</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="font-size: small;"><strong>makecert -r -pe -n "CN=RisingAPIClient" -ss My -len 2048 RisingAPIClient.cer</strong></span></p>
<p><span style="font-size: small;">&nbsp; 9. Certificate need to be associated with the registered client application in Azure AD. This can be done using Azure AD module for Powershell. Install the module from this <a title="link" href="https://technet.microsoft.com/en-us/library/jj151815.aspx" target="_blank">link</a>.</span></p>
<p><span style="font-size: small;">&nbsp; 10. After you have installed the module, run the following commands from a Powershell command window:</span></p>
<ul>
<li>PS C:\windows\system32&gt; <span style="font-size: small;"><strong>connect-msolservice</strong></span></li>
</ul>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="font-size: small;">&nbsp; (Enter your username and password for the Azure AD user, when prompted. For example, ajay@risingventure.onmicrosoft.com , p@$$w0rd . Note that the user must be part of this specific AD and should have username like *@risingventure.onmicrosoft.com. In azure portal, the account that creates the Azure AD is automatically added as an user to the newly created AD. This account may not work for adding certificate credentials for applications in newly created AD. Also, note that the user account which registered the client application on AD or a global administrator of the AD will have permissions to add certificate credentials.)</span></p>
<ul>
<li>PS C:\windows\system32&gt;<strong><span style="font-size: small;"> $cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate</span></strong></li>
<li>PS C:\windows\system32&gt;<span style="font-size: small;"><strong> $cer.Import("E:\Certs\RisingAPIClient.cer")</strong></span> &nbsp; &nbsp; (Path to the created certificate)</li>
<li>PS C:\windows\system32&gt; <span style="font-size: small;"><strong>$binCert = $cer.GetRawCertData()</strong></span></li>
<li>PS C:\windows\system32&gt; <strong><span style="font-size: small;">$credValue = [System.Convert]::ToBase64String($binCert)</span></strong></li>
<li>PS C:\windows\system32&gt; <span style="font-size: small;"><strong>New-MsolServicePrincipalCredential -AppPrincipalId "&lt;client ID&gt;" -Type asymmetric -Value $credValue -Usage verify</strong></span></li>
</ul>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="font-size: small;"> (clientId = f5c69304-8c94-48e5-9dac-d9742ca021aa for our client application). If you get Access Denied error, then check if the same user created the client application on Azure portal that you used to login in the first powershell command of 'connect-msolservice'. Otherwise, get these commands executed under a global administrator account.</span></p>
<p><span style="font-size: small;">&nbsp; 11. Install the certificate created in step 8 on the machine where you intend to run the client from. It should be installed in the current user personal store. Note its thumbprint.</span></p>
<p><span style="font-size: large;"><strong><span style="text-decoration: underline;">4. Creating client application</span></strong></span></p>
<p><span style="font-size: small;">&nbsp; 1. Create a console application in Visual Studio.</span></p>
<p><span style="font-size: small;">&nbsp; 2. Install nuget package 'Active Directory Authentication Library'.</span></p>
<p><span style="font-size: small;">&nbsp; 3. Add reference to .Net framework assemblies - System.Net, System.Net.Http, System.Configuration.</span></p>
<p><span style="font-size: small;">&nbsp; 4. Add the following configuration to the App.Config:</span></p>
<pre class="scroll"><code class="csharp"> &lt;add key="AADInstance" value="https://login.windows.net/{0}" /&gt;<br /> &lt;add key="Tenant" value="risingventure.onmicrosoft.com" /&gt; &lt;!-- Azure AD tenant --&gt;<br /> &lt;add key="ClientId" value="f5c69304-8c94-48e5-9dac-d9742ca021aa" /&gt; &lt;!-- Client ID of the registered client application on AD --&gt;<br /> &lt;add key="CertThumbprint" value="e21bcf7d735077324f8cf5cf9b21b81cf852f6a7" /&gt; &lt;!-- Thumbprint of the certificate created in last section --&gt;<br /> &lt;add key="ApiResourceId" value="https://risingventure.onmicrsoft.com/risingwebapi" /&gt; &lt;!-- APP ID URI of the Web API registered with AD --&gt;<br /> &lt;add key="ApiBaseAddress" value="https://localhost:10000/" /&gt; &lt;!-- Actual URL where Web API is hosted --&gt;</code></pre>
<pre><span style="font-size: small;">5. Put the following code to the program.cs:</span></pre>
<pre class="scroll"><code class="csharp">using Microsoft.IdentityModel.Clients.ActiveDirectory;<br /> using System;<br /> using System.Configuration;<br /> using System.Globalization;<br /> using System.Net.Http;<br /> using System.Net.Http.Headers;<br /> using System.Security.Cryptography.X509Certificates;<br /> using System.Threading.Tasks;<br /> <br /> namespace RisingAPIClient<br /> {<br /> class Program<br /> {<br /> private static string aadInstance = ConfigurationManager.AppSettings["AADInstance"];<br /> private static string tenant = ConfigurationManager.AppSettings["Tenant"];<br /> private static string clientId = ConfigurationManager.AppSettings["ClientId"];<br /> private static string certThumbprint = ConfigurationManager.AppSettings["CertThumbprint"];<br /> static string authority = String.Format(CultureInfo.InvariantCulture, aadInstance, tenant);<br /> private static string apiResourceId = ConfigurationManager.AppSettings["ApiResourceId"];<br /> private static string apiBaseAddress = ConfigurationManager.AppSettings["ApiBaseAddress"];<br /> private static HttpClient httpClient = new HttpClient();<br /> private static AuthenticationContext authContext = null;<br /> private static ClientAssertionCertificate certCred = null; <br /> <br /> static void Main(string[] args)<br /> {<br /> bool retValue = CallWebAPI().Result;<br /> Console.WriteLine("Completed");<br /> Console.ReadKey();<br /> }<br /> <br /> static async Task&lt;bool&gt; CallWebAPI()<br /> {<br /> authContext = new AuthenticationContext(authority);<br /> X509Certificate2 cert = null;<br /> X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);<br /> try<br /> {<br /> store.Open(OpenFlags.ReadOnly);<br /> cert = store.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false)[0];<br /> }<br /> finally<br /> {<br /> store.Close();<br /> }<br /> certCred = new ClientAssertionCertificate(clientId, cert);<br /> AuthenticationResult result = null;<br /> try<br /> { <br /> result = await authContext.AcquireTokenAsync(apiResourceId, certCred); <br /> }<br /> catch (AdalException)<br /> {<br /> //May be retry<br /> }<br /> httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);<br /> HttpResponseMessage response = null;<br /> try<br /> {<br /> response = await httpClient.GetAsync(apiBaseAddress + "api/getdata");<br /> }<br /> catch (Exception ex)<br /> {<br /> Console.WriteLine(ex.Message);<br /> }<br /> if (response.IsSuccessStatusCode)<br /> {<br /> string s = await response.Content.ReadAsStringAsync();<br /> Console.WriteLine(s);<br /> }<br /> else<br /> {<br /> Console.WriteLine("ERROR :" + response.StatusCode);<br /> }<br /> return true;<br /> }<br /> }<br /> }</code></pre>
<pre><span style="font-size: small;">6. Run the Web API solution first and then run the client solution.&nbsp;</span></pre>
<pre><span style="font-size: small;"> The client should be able to access the WebAPI and fetach the data.</span></pre>
<p><span style="text-decoration: underline; font-size: large;"><strong>5. Getting client claims on the server (Web API) side</strong></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">Client details can be fetched on the server side by from the current claims principals. For example you can get the Object ID of the client using the following code:</span></p>
<pre class="scroll"><code class="csharp">Claim clientClaim = ClaimsPrincipal.Current.FindFirst("https://schemas.microsoft.com/identity/claims/objectidentifier"); //You may have to include System.Security.Claims namespace. <br /> string objectId = clientClaim.Value;</code></pre>
<p style="padding-left: 30px;"><span style="font-size: small;">Object ID is an immutable and globally unique identifier and can be used for authorization purposes. Read more about it <a title="here" href="https://msdn.microsoft.com/en-us/library/azure/dn385718.aspx" target="_blank">here</a>.</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">You can also get other claims:</span></p>
<p style="padding-left: 30px;">&nbsp;&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1651.claims.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1651.claims.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/1651.claims.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/1651.claims.png" alt="" border="0" /></a>&nbsp;</p>
<p><span style="font-size: large;"><strong><span style="text-decoration: underline;">6. Removing certificate authentication for the client</span></strong></span></p>
<p><span style="font-size: small;">&nbsp; You should have Azure AD module for powershell installed as described earlier.</span></p>
<p><span style="font-size: small;">&nbsp; 1. Run the following command in powershell to get the Key Id:</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="font-size: small;"><strong>Get-MsolServicePrincipalCredential &ndash;ServicePrincipalName &ldquo;&lt;App ID URI of client &gt;&rdquo; -ReturnKeyValues 0 &nbsp; &nbsp;</strong></span> &nbsp; &nbsp;</p>
<p><span style="font-size: small;">(App ID URI of client e.g. https://risingapiclient/)</span></p>
<p><span style="font-size: small;">&nbsp; &nbsp;You will get the following output:</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="Apple-tab-span" style="white-space: pre;"> <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/4645.keyid.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/4645.keyid.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/4645.keyid.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/4645.keyid.png" alt="" border="0" /></a> </span>&nbsp;</p>
<p>&nbsp;<span style="font-size: small;"> &nbsp; Note the KeyId.</span></p>
<p><span style="font-size: small;">&nbsp; 2. Next run the following command:</span></p>
<p><span style="font-size: small;"><strong>&nbsp; &nbsp; &nbsp;<span class="Apple-tab-span" style="white-space: pre;"> Remove-MsolServicePrincipalCredential -KeyIds @("5ab1d398-a42f-4f99-9981-cca0c985ff67") </span></strong></span></p>
<p><span style="font-size: small;"><strong>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-tab-span" style="white-space: pre;">-ServicePrincipalName "https://risingapiclient/"</span></strong></span></p>
<p><span style="text-decoration: underline; font-size: large;"><strong>7. Using Keys instead of certificate to authenticate client</strong></span></p>
<p><span style="font-size: small;">&nbsp; 1. Sign in to Azure portal. Go to AD and go to 'CONFIGURE' tab of the client application.</span></p>
<p><span style="font-size: small;">&nbsp; 2. Under 'Keys' section, select the duration of the validity of the key. Next click on save at the bottom to make the key visible.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8371.keys2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8371.keys2.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8371.keys2.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8371.keys2.png" alt="" border="0" /></a>&nbsp;&nbsp;</p>
<p><span style="font-size: small;">&nbsp; 3. Copy the key. Note that you would not be able to retrieve the key after you leave the page.</span></p>
<p><span style="font-size: small;">&nbsp; 4. Add the following app setting to App.config file of client project: &nbsp; &nbsp; &nbsp;</span><span style="color: #808080; font-family: 'courier new', courier;">&nbsp;</span></p>
<pre class="scroll"><code class="csharp">&lt;add key="AppKey" value="&lt;Key retrieved from portal&gt;"/&gt;</code>&nbsp;</pre>
<p>&nbsp; <span style="font-size: small;">5. Do the following changes to program.cs:</span></p>
<p><span style="font-size: small;">&nbsp; &nbsp; &nbsp; &nbsp;In place of&nbsp;</span></p>
<pre class="scroll"><code class="csharp">X509Certificate2 cert = null;<br /> X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);<br /> try<br /> {<br /> store.Open(OpenFlags.ReadOnly);<br /> cert = store.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false)[0];<br /> }<br /> finally<br /> {<br /> store.Close();<br /> }<br /> certCred = new ClientAssertionCertificate(clientId, cert);</code></pre>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<span style="font-size: small;">Put</span></p>
<pre class="scroll"><code class="csharp"> string appKey = ConfigurationManager.AppSettings["AppKey"];<br /> ClientCredential clientCredential = new ClientCredential(clientId, appKey);</code></pre>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<span style="font-size: small;">And, in place of &nbsp; &nbsp; &nbsp;</span> &nbsp; &nbsp; &nbsp; &nbsp;</p>
<pre class="scroll"><code class="csharp"> result = await authContext.AcquireTokenAsync(apiResourceId, certCred); </code><span class="Apple-tab-span" style="white-space: pre; font-family: 'courier new', courier; color: #ff0000;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span></pre>
<p>&nbsp; <span style="font-size: small;">&nbsp; &nbsp; &nbsp;put &nbsp; &nbsp;</span> &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p>
<pre class="scroll"><code class="csharp"> result = authContext.AcquireToken(apiResourceId, clientCredential);</code></pre>
<p><span style="font-size: small;">&nbsp; 6. Now run the client again. It should be able to access the Web API.</span></p>
<p><strong style="font-size: large;"><span style="text-decoration: underline;">8. Fetching Object ID for a certificate or key authenticated AD client</span></strong></p>
<p><span style="font-size: small;">&nbsp; You may be required to get the Object ID of a client that uses certificate or key authentication to AD to on-board to some custom authorization logic.</span></p>
<p><span style="font-size: small;">&nbsp; For this, you should have the Azure AD module for powershell installed as described earlier. Run the following commands to get the Object ID:</span></p>
<ul>
<li>&nbsp; &nbsp;&nbsp;<span style="font-size: small;"><strong>connect-msolservice &nbsp; &nbsp;</strong></span></li>
</ul>
<p>&nbsp;<span style="font-size: small;">(Enter AD username and password as before)</span></p>
<ul>
<li><span style="font-size: small;"><strong>Get-MsolServicePrincipal -AppPrincipalId '&lt;Client ID&gt;'</strong></span></li>
</ul>
<p><span style="font-size: small;">&nbsp;(Client ID of the registered application, e.g. f5c69304-8c94-48e5-9dac-d9742ca021aa)</span></p>
<p><span style="font-size: small;">&nbsp; &nbsp;It should give you the ObjectId as below:</span></p>
<p>&nbsp; &nbsp; &nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/4188.clientid.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/4188.clientid.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/4188.clientid.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/4188.clientid.png" alt="" border="0" /></a>&nbsp;</p>
<p><span style="text-decoration: underline; font-size: large;"><strong>9. Using username and password instead of certificate/key authentication</strong></span></p>
<p><span style="font-size: small;">&nbsp; An actual user can authenticate to AD rather than an application identity. However for this to work the registering of client on the Ad is little different. We will create a new client in AD.</span></p>
<p><span style="font-size: small;">&nbsp; 1. Refer to the above section of 'Registering Client with Azure AD Tenant' and follow steps 1-3.</span></p>
<p><span style="font-size: small;">&nbsp; 2. Give the name of the application as 'RisingAPINativeClient'. Select 'NATIVE CLIENT APPLICATION'. Click next.</span></p>
<p><span style="font-size: small;">&nbsp; 3. Enter any valid URI (e.g. https://nativeclient/) in the 'Redirect URI' field and click OK mark to create the application.</span></p>
<p><span style="font-size: small;">&nbsp; 4. Go to configure tab and copy the client id. Also give the application access to Web API by following step 7 from&nbsp;section 'Registering Client with Azure AD Tenant' .</span></p>
<p><span style="font-size: small;">&nbsp; 5. In the client project, change the config value of client id to be of the newly created client application.</span></p>
<p><span style="font-size: small;">&nbsp; 6. Do the following change to the program.cs:</span></p>
<p><span style="font-size: small;">&nbsp; &nbsp; &nbsp; &nbsp;Replace the line</span>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p>
<pre class="scroll"><code class="csharp"> result = authContext.AcquireToken(apiResourceId, clientCredential); </code></pre>
<p>&nbsp; &nbsp; &nbsp; &nbsp;<span style="font-size: small;">With</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p>
<pre class="scroll"><code class="csharp">result = authContext.AcquireToken(apiResourceId, clientId, new Uri("https://nativeclient/"), PromptBehavior.Always); </code></pre>
<p><span style="font-size: small;">&nbsp; 7. Run the client application now. You will get a prompt for username and password.</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="Apple-tab-span" style="white-space: pre;"> <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8030.prompt.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8030.prompt.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/70/04/8030.prompt.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-70-04/8030.prompt.png" alt="" border="0" /></a></span>&nbsp;&nbsp;</p>
<p><span style="font-size: small;">&nbsp; 8. Sign in with an AD account. The Web API will accessible through this way also.</span></p>
<p><span style="font-size: small;">&nbsp; 9. You can get the get the user details the same way on the server side from claims principals. This time there would be more claims pertaining to user details. If you want to fetch the user details for on-boarding purposes, you can get it through <a title="Graph API" href="https://msdn.microsoft.com/library/azure/hh974476.aspx" target="_blank">Graph API</a>.&nbsp;</span></p>
<p><span style="text-decoration: underline; font-size: large;"><strong>10. Read more/ References</strong></span></p>
<ul>
<li><span style="font-size: small;"><a href="https://azure.microsoft.com/en-us/documentation/services/active-directory/" target="_blank">Azure Active Directory documentation</a></span></li>
<li><span style="font-size: small;"><a href="https://msdn.microsoft.com/en-us/library/hh974476.aspx" target="_blank">Azure AD Graph API</a></span></li>
<li><span style="font-size: small;"><a href="https://msdn.microsoft.com/en-us/library/azure/dn646737.aspx" target="_blank">Azure AD samples</a></span></li>
<li><span style="font-size: small;"><a href="https://msdn.microsoft.com/en-us/library/azure/dn499820.aspx" target="_blank">Authentication Scenarios and Basic Principles</a></span></li>
<li><span style="font-size: small;"><a href="https://technet.microsoft.com/en-us/library/jj151815.aspx" target="_blank">Azure AD Powershell Documentation</a></span></li>
</ul>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>