{"id":2786,"date":"2014-04-28T07:48:33","date_gmt":"2014-04-28T14:48:33","guid":{"rendered":"http:\/\/www.cloudidentity.com\/blog\/?p=2786"},"modified":"2014-04-28T23:40:46","modified_gmt":"2014-04-29T06:40:46","slug":"use-owin-azure-ad-to-secure-both-mvc-ux-and-web-api-in-the-same-project","status":"publish","type":"post","link":"https:\/\/www.cloudidentity.com\/blog\/2014\/04\/28\/use-owin-azure-ad-to-secure-both-mvc-ux-and-web-api-in-the-same-project\/","title":{"rendered":"Use OWIN &amp; Azure AD to Secure Both MVC UX and Web API in The Same Project"},"content":{"rendered":"<p>Mixing and matching multiple authentication styles in a single web application has always been difficult with WIF.<br \/>\nThe new OWIN security components in ASP.NET change that, thanks to the finer grained control they grant over request processing pipelines.<\/p>\n<p>One of the most common requests I have been hearing in the last couple of years is \u2013 how can one secure both UX controllers and API controllers within the same app? This post is meant to show you how to do exactly that.<\/p>\n<p>I will start from an MVC app, already configured to handle web sign in via Azure AD thru OpenId Connect. I will add to the app a web API controller, show how to configure it to accepts calls secured via OAuth2 bearer token access from Azure AD, put together a quick test client and demonstrate how OpenID Connect and OAuth2 can coexist in the very same VS project. Pretty cool!<\/p>\n<h2>Set Up an App to Use OpenId Connect and Azure AD<\/h2>\n<p>Rather than starting from scratch, I recommend that you clone our basic web sign on sample from <a title=\"WebApp-OpenIDConnect-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/WebApp-OpenIDConnect-DotNet\">WebApp-OpenIDConnect-DotNet<\/a>. Clone it and follow the instructions in the \u201cHow to run this sample\u201d section in the readme. Once done, confirm that everything went well by hitting F5 and doing a test sign in. If everything works as described, you are ready to move to the next phase.<\/p>\n<h2>Add a Web API Controller<\/h2>\n<p>Next, we are going to add to the app\u2019s controllers an ApiController and configure the app to correctly route requests through it. No identity work yet.<\/p>\n<p>Right-click on the project in the solution explorer, choose add new\/controller.<\/p>\n<p>Choose <strong>Web API 2 Controller \u2013 Empty<\/strong>. I named mine AphorismController.<\/p>\n<p>The scaffolding system goes as far as it can for adding the necessary bits to the project (the AphorismController.cs file, the WebApiConfig.cs file in App_Start) but it does not do everything for you; namely, there are some required changes in the global.asax.cs file that you have to apply manually. The good news is that the scaffolding helps you by listing those changes in a readme.txt that gets displayed as soon as it\u2019s done updating the project. Specifically, you have to add to the Application_Start the <strong><span style=\"background-color: #ffff00;\">following lines<\/span><\/strong>:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> System;\r\n<span class=\"kwrd\">using<\/span> System.Collections.Generic;\r\n<span class=\"kwrd\">using<\/span> System.Linq;\r\n<span class=\"kwrd\">using<\/span> System.Web;\r\n<span class=\"kwrd\">using<\/span> System.Web.Mvc;\r\n<span class=\"kwrd\">using<\/span> System.Web.Optimization;\r\n<span class=\"kwrd\">using<\/span> System.Web.Routing;\r\n<strong><span style=\"background-color: #ffff00;\"><span class=\"kwrd\">using<\/span> System.Web.Http;<\/span><\/strong>\r\n\r\n<span class=\"kwrd\">namespace<\/span> WebApp_OpenIDConnect_DotNet\r\n{\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> MvcApplication : System.Web.HttpApplication\r\n    {\r\n        <span class=\"kwrd\">protected<\/span> <span class=\"kwrd\">void<\/span> Application_Start()\r\n        {            \r\n            AreaRegistration.RegisterAllAreas();\r\n            <strong><span style=\"background-color: #ffff00;\">GlobalConfiguration.Configure(WebApiConfig.Register);<\/span><\/strong>\r\n            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);\r\n            RouteConfig.RegisterRoutes(RouteTable.Routes);\r\n            BundleConfig.RegisterBundles(BundleTable.Bundles);\r\n        }\r\n    }\r\n}<\/pre>\n<p>Once you\u2019ve done that, we need to add an action to our new controller \u2013 just to see some action (no pun intended). Here there\u2019s mine:<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AphorismController : ApiController\r\n{\r\n    <span class=\"kwrd\">public<\/span> <span class=\"kwrd\">string<\/span> Get()\r\n    {\r\n        <span class=\"kwrd\">string<\/span> [] aphorisms = \r\n            <span class=\"kwrd\">new<\/span> [] {<span class=\"str\">\"Non ci sono piu' le mezze stagioni\"<\/span>,\r\n                    <span class=\"str\">\"Tanto va la gatta al lardo che ci lascia lo zampino\"<\/span>,\r\n                    <span class=\"str\">\"La twingo e' una macchina terribile\"<\/span>};\r\n        <span class=\"kwrd\">return<\/span> (aphorisms[<span class=\"kwrd\">new<\/span> Random().Next(3)]);\r\n    }\r\n}\r\n<\/pre>\n<p>This web API will dispense a random tidbit of ancient Italian wisdom to anybody hitting via the browser the URL <a title=\"https:\/\/localhost:44320\/API\/Aphorism\" href=\"https:\/\/localhost:44320\/API\/Aphorism\">https:\/\/localhost:44320\/API\/Aphorism<\/a>\u00a0<img decoding=\"async\" class=\"wlEmoticon wlEmoticon-winkingsmile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/wlEmoticon-winkingsmile1.png\" alt=\"Winking smile\" \/>.<\/p>\n<p>Go ahead, hit F5 and give it a try now &#8211; before we start playing with identity\u00a0 -to ensure that the controller was correctly added . Note that you can hit the API endpoint anonymously and get results regardless of whether you signed in the app via web sign in or not \u2013 that\u2019s because the API controller we added is not secured yet.<\/p>\n<h2>Securing the Web API with Azure AD<\/h2>\n<p>Aaand here the fun begins. We know from <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/dn463788.aspx\">past entries<\/a> that the ASP.NET OWIN components include middleware specifically designed to secure web API via Azure AD and OAuth2 bearer token access. All we need to do here is to add the relevant middleware to the pipeline \u2013 ensuring that it does not step on the toes of the middleware already there (the OpenId Connect one, handling requests to the controllers which serve UX to the browser). That boils down to ensuring that the OpenId Connect middleware fires when the request involves UX, and that the Azure AD OAuth2 bearer token middleware fires only when the request is for a web API.<\/p>\n<p>From the Package Manger Console, run<\/p>\n<p><span style=\"font-family: Courier New;\">PM&gt; Install-Package Microsoft.Owin.Security.ActiveDirectory -Pre<br \/>\nPM&gt; Install-Package Microsoft.AspNet.WebApi.Owin -Pre<\/span><\/p>\n<p>The first package contains the Azure AD OAuth2 middleware; the second contains classes used for using OWIN components with web API.<\/p>\n<p>That done, head to Startup.Auth.cs and add the following highlighted code:<\/p>\n<pre class=\"csharpcode\"><span class=\"rem\">\/\/ ...<\/span><\/pre>\n<pre class=\"csharpcode\"><strong><span style=\"background-color: #ffff00;\"><span class=\"kwrd\">using<\/span> Microsoft.Owin.Security.ActiveDirectory;<\/span><\/strong>\r\n<span class=\"rem\">\/\/ ...<\/span>\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">void<\/span> ConfigureAuth(IAppBuilder app)\r\n{\r\n    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);\r\n\r\n    app.UseCookieAuthentication(<span class=\"kwrd\">new<\/span> CookieAuthenticationOptions());\r\n\r\n    app.UseOpenIdConnectAuthentication(\r\n        <span class=\"kwrd\">new<\/span> OpenIdConnectAuthenticationOptions\r\n        {\r\n            Client_Id = clientId,\r\n            Authority = authority,\r\n            Post_Logout_Redirect_Uri = postLogoutRedirectUri\r\n        });\r\n<strong><span style=\"background-color: #ffff00;\">    app.UseWindowsAzureActiveDirectoryBearerAuthentication(\r\n        <span class=\"kwrd\">new<\/span> WindowsAzureActiveDirectoryBearerAuthenticationOptions\r\n        {\r\n            Audience = <span class=\"str\">\"https:\/\/developertenant.onmicrosoft.com\/WebUXplusAPI\"<\/span>,\r\n            Tenant = <span class=\"str\">\"developertenant.onmicrosoft.com\"<\/span>,\r\n            AuthenticationType = <span class=\"str\">\"OAuth2Bearer\"<\/span>,                               \r\n        });<\/span><\/strong>\r\n}<\/pre>\n<p>The call to UseWindowsActiveDirectoryBearerAuthentication adds the relevant middleware to the pipeline. The tenant is the same we\u2019ve used so far, and the Audience value comes straight from the App Id URI entry for the app in the Azure AD portal.<br \/>\nThe notable bit here is the value assigned to AuthenticationType. Both the cookie and the OpenId Connect middlewares stick with the same default, assigned in the first line of ConfigureAuth; but the OAuth2 middleware gets a different value, to ensure that the activation paths of the two middleware groups remain distinct.<\/p>\n<p>Here there\u2019s how we take advantage of that. Head to your API controller class and add the following:<\/p>\n<pre class=\"csharpcode\"><span style=\"background-color: #ffff00;\">[HostAuthentication(<span class=\"str\">\"OAuth2Bearer\"<\/span>)]\r\n[Authorize]<\/span>\r\n<span class=\"kwrd\">public<\/span> <span class=\"kwrd\">class<\/span> AphorismController : ApiController\r\n{\r\n<\/pre>\n<p>The [Authorize] attribute establishes that only authenticated users are allowed to request any of the resources served by the controller. The value of HostAuthentication reflects the value specified in the initialization of the Azure AD OAuth2 web API middleware, creating a tie between the two and determining what middleware will fire upon receiving a request for this controller.<\/p>\n<p>Go ahead and try hitting again the endpoint via browser: this time you\u2019ll get back a 401.<\/p>\n<h2>Update the Azure AD Portal to Provision the Web API and Its Client<\/h2>\n<p>Currently we have a regression which requires you to do a bit of extra work for AD to recognize that, besides the UX, your web app exposes a web API. You can follow the instructions for adding a manifest entry to the API as presented in <a title=\"https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet\">https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet<\/a>, step #3, register service.<\/p>\n<p>Once that\u2019s done, you have to create an entry for a client app to securely exercise the web API end point. You can follow the instructions in <a title=\"https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet\" href=\"https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet\">https:\/\/github.com\/AzureADSamples\/NativeClient-DotNet<\/a>, step #, register client.<\/p>\n<h2>Create the Client Project<\/h2>\n<p>This is standard ADAL usage. Add to the solution a new project: I used a console app to kame things faster, but of course you can choose any time of client you like.<\/p>\n<p>Once you have the project, get in the package manager console and run the two commands below.<\/p>\n<p><span style=\"font-family: Courier New;\">PM&gt; Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory \u2013Pre<br \/>\n<\/span><span style=\"font-family: Courier New;\">PM&gt; Install-Package Microsoft.Net.Http -Pre<\/span><\/p>\n<p>That\u2019s pretty much it. The client is all boilerplate code, you can just paste the below in your project and simply change the AuthenticationContext construction and AccessToken call to use your actual settings.<\/p>\n<pre class=\"csharpcode\"><span class=\"kwrd\">using<\/span> System;\r\n<span class=\"kwrd\">using<\/span> Microsoft.IdentityModel.Clients.ActiveDirectory;\r\n<span class=\"kwrd\">using<\/span> System.Net.Http;\r\n<span class=\"kwrd\">using<\/span> System.Net.Http.Headers;\r\n\r\n<span class=\"kwrd\">namespace<\/span> Client1\r\n{\r\n    <span class=\"kwrd\">class<\/span> Program\r\n    {\r\n        <span class=\"kwrd\">static<\/span> <span class=\"kwrd\">void<\/span> Main(<span class=\"kwrd\">string<\/span>[] args)\r\n        {\r\n            AuthenticationContext ac = \r\n                <span class=\"kwrd\">new<\/span> AuthenticationContext(<span class=\"str\">\"https:\/\/login.windows.net\/developertenant.onmicrosoft.com\"<\/span>);\r\n            AuthenticationResult ar = \r\n                ac.AcquireToken(<span class=\"str\">\"https:\/\/developertenant.onmicrosoft.com\/WebUXplusAPI\"<\/span>, \r\n                                <span class=\"str\">\"71aefb3b-9218-4dea-91f2-8b23ce93f387\"<\/span>, \r\n                                <span class=\"kwrd\">new<\/span> Uri(<span class=\"str\">\"http:\/\/any\"<\/span>));\r\n\r\n            <span class=\"kwrd\">string<\/span> result = <span class=\"kwrd\">string<\/span>.Empty;\r\n            HttpClient httpClient = <span class=\"kwrd\">new<\/span> HttpClient();\r\n            httpClient.DefaultRequestHeaders.Authorization = \r\n                <span class=\"kwrd\">new<\/span> AuthenticationHeaderValue(<span class=\"str\">\"Bearer\"<\/span>, ar.AccessToken);\r\n            HttpResponseMessage response = \r\n                httpClient.GetAsync(<span class=\"str\">\"https:\/\/localhost:44320\/API\/Aphorism\"<\/span>).Result;\r\n\r\n            <span class=\"kwrd\">if<\/span> (response.IsSuccessStatusCode)\r\n            {\r\n                result = response.Content.ReadAsStringAsync().Result;\r\n            }\r\n            Console.WriteLine(result);\r\n            Console.ReadLine();\r\n        }\r\n    }\r\n}<\/pre>\n<h2>Test Run<\/h2>\n<p>Hit F5. The web app project will start. Either leave it as is or sign in, it makes no difference for the web API.<\/p>\n<p>Next, right-click on your client project and choose debug\/start new instance.<\/p>\n<p>You\u2019ll be prompted right away.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/image4.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/image_thumb4.png\" alt=\"image\" width=\"640\" height=\"469\" border=\"0\" \/><\/a><\/p>\n<p>Sign in with a user from your development tenant, and voila\u2019! You securely accessed via OAuth2 bearer token a web API, hosted alongside UX secured via OpenId Connect.<\/p>\n<p><a href=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/image5.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-width: 0px;\" title=\"image\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/image_thumb5.png\" alt=\"image\" width=\"640\" height=\"417\" border=\"0\" \/><\/a><\/p>\n<h2>Wrap<\/h2>\n<p>This is one of the many scenarios that were difficult to achieve with the former programming model, but that we explicitly designed for in the new OWIN security components. In fact, as you have seen achieving peaceful coexistence of UX and API controllers in the same project is trivial with the new middleware.<br \/>\nI know for a fact that many of you will be super happy to read this <img decoding=\"async\" class=\"wlEmoticon wlEmoticon-smile\" src=\"https:\/\/www.cloudidentity.com\/blog\/wp-content\/uploads\/2014\/04\/wlEmoticon-smile2.png\" alt=\"Smile\" \/> if you have feedback on how we can improve this further, don\u2019t be shy!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mixing and matching multiple authentication styles in a single web application has always been difficult with WIF. The new OWIN security components in ASP.NET change that, thanks to the finer grained control they grant over request processing pipelines. One of the most common requests I have been hearing in the last couple of&#8230;<\/p>\n","protected":false},"author":1,"featured_media":2782,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2786","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2786","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/comments?post=2786"}],"version-history":[{"count":2,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2786\/revisions"}],"predecessor-version":[{"id":2788,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/posts\/2786\/revisions\/2788"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media\/2782"}],"wp:attachment":[{"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/media?parent=2786"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/categories?post=2786"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudidentity.com\/blog\/wp-json\/wp\/v2\/tags?post=2786"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}