Recently I’ve received lot of comments and emails asking how we can decouple the OWIN Authorization Server we’ve built in the previous posts from the resources we are protecting. If you are following the posts mentioned below you will notice that we’ve only one software component (API) which plays both roles: Authorization Server and Resource Server.
There is nothing wrong with the the current implementation because OAuth 2.0 specifications never forces the separation between the Authorization Server and the Resource Server, but in many cases and especially if you have huge resources and huge number of endpoints you want to secure; then it is better from architecture stand point to decouple the servers. So you will end up having a stand alone Authorization Server, and another stand alone Resource Server which contains all protected resources, as well this Resource Server will understand only the access tokens issued from the Authorization Server.
You can check the source code on Github.
- Token Based Authentication using ASP.NET Web API 2, Owin, and Identity – Part 1.
- AngularJS Token Authentication using ASP.NET Web API 2, Owin, and Identity – Part 2.
- Enable OAuth Refresh Tokens in AngularJS App using ASP .NET Web API 2, and Owin – Part 3.
- ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app – Part 4.
- Update Oct-27 New post: better approach to Decouple Authorization Server from Resource Server by using JSON Web Tokens (JWT).
OAuth 2.0 Roles: Authorization Server, Resource Server, Client, and Resource Owner
Before we jump into implementation and how we can decouple the servers I would like to emphasis on OAuth 2.0 roles defined in the specifications; so we’ll have better understanding of the responsibility of each role, by looking at the image below you will notice that there are 4 roles involved:
Resource Owner:
The entity or person (user) that owns the protected Resource.
Resource Server:
The server which hosts the protected resources, this server should be able to accept the access tokens issued by the Authorization Server and respond with the protected resource if the the access token is valid.
Client Applications:
The application or the (software) requesting access to the protected resources on the Resource Server, this client (on some OAuth flows) can request access token on behalf of the Resource Owner.
Authorization Server:
The server which is responsible for managing authorizations and issuing access tokens to the clients after validating the Resource Owner identity.
Note: In our architecture we can have single Authorization Server which is responsible to issue access token which can be consumed by multiple Resource Servers.
Decoupling OAuth 2.0 OWIN Authorization Server from Resource Server
In the previous posts we’ve built the Authorization Server and the Resource Server using a single software component (API), this API can be accessed on (http://ngauthenticationAPI.azurewebsites.net), in this demo I will guide you on how to create new standalone Resource API and host it on different machine other than the Authorization Server machine, then configure the Resource API to accept only access tokens issued from our Authorization Server. This new Resource Server is hosted on Azure can be accessed on (http://ngauthenticationResourcesAPI.azurewebsites.net).
Note: As you noticed from the previous posts we’ve built a protected resource (OrdersController) which can be accessed by issuing HTTP GET to the end point(http://ngauthenticationAPI.azurewebsites.net/api/orders), this end point is considered as a resource and should be moved to the Resource Server we’ll build now, but for the sake of keeping all the posts on this series functioning correctly; I’ll keep this end point in our Authorization Server, so please consider the API we’ve built previously as our standalone Authorization Server even it has a protected resource in it.
Steps to build the Resource Server
In the steps below, we’ll build another Web API which will contain our protected resources, for the sake of keeping it simple, I’ll add only one secured end point named “ProtectedController”, any authorized request to this end point should contain valid bearer token issued from our Authorization Server, so let’s start implementing this:
Step 1: Creating the Resource Web API Project
We need to add new ASP.NET Web application named “AngularJSAuthentication.ResourceServer” to our existing solution named “AngularJSAuthentication”, the selected template for the new project will be “Empty” template with no core dependencies, check the image below:
Step 2: Install the needed NuGet Packages
This project is empty so we need to install the NuGet packages needed to setup our OWIN Resource Server, configure ASP.NET Web API to be hosted within an OWIN server, and configure it to only uses OAuth 2.0 bearer tokens as authorization middle ware; so open NuGet Package Manager Console and install the below packages:
1 2 3 4 5 |
Install-Package Microsoft.AspNet.WebApi -Version 5.2.2 Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.2.2 Install-Package Microsoft.Owin.Host.SystemWeb -Version 3.0.0 Install-Package Microsoft.Owin.Cors -Version 3.0.0 Install-Package Microsoft.Owin.Security.OAuth -Version 2.1.0 |
The usage for each package has been covered on the previews posts, feel free to check this post to know the rational of using each package is used for.
Important note: In the initial post I was using package “Microsoft.Owin.Security.OAuth” version “3.0.0” which differs from the version used in the Authorization Server version “2.1.0”, there was a bug in my solution when I was using 2 different versions, basically the bug happens when we send an expired token to the Resource Server, the result for this that Resource Server accepts this token even if it is expired. I’ve noticed that the properties for the Authentication ticket are null and there is no expiry date. To fix this issue we need to unify the assembly version “Microsoft.Owin.Security.OAuth” between the Authorization Server and the Resource Server, I believe there is breaking changes between those 2 versions that’s why ticket properties are not de-crypted and de-serialized correctly. Thanks for Ashish Verma for notifying me about this.
Step 3: Add OWIN “Startup” Class
Now we want to add new class named “Startup”. It will contain the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[assembly: OwinStartup(typeof(AngularJSAuthentication.ResourceServer.Startup))] namespace AngularJSAuthentication.ResourceServer { public class Startup { public void Configuration(IAppBuilder app) { HttpConfiguration config = new HttpConfiguration(); ConfigureOAuth(app); WebApiConfig.Register(config); app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); app.UseWebApi(config); } private void ConfigureOAuth(IAppBuilder app) { //Token Consumption app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions { }); } } } |
As we’ve covered in previous posts, this class will be fired once our Resource Server starts, as you noticed I’ve enabled CORS so this resource server can accept XHR requests coming from any origin.
What worth noting here is the implementation for method “ConfigureOAuth”, inside this method we are configuring the Resource Server to accept (consume only) tokens with bearer scheme, if you forget this one; then your Resource Server won’t understand the bearer tokens sent to it.
Step 3: Add “WebApiConfig” Class
As usual we need to add the WebApiConfig class under folder “App_Start” which contains the code below:
1 2 3 4 5 6 7 8 9 10 11 |
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First(); jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); } } |
This class is responsible to enable routing attributes on our controller.
Step 4: Add new protected (secured) controller
Now we want to add a controller which will serve as our protected resource, this controller will return list of claims for the authorized user, those claims for sure are encoded within the access token we’ve obtained from the Authorization Server. So add new controller named “ProtectedController” under “Controllers” folder and paste the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[Authorize] [RoutePrefix("api/protected")] public class ProtectedController : ApiController { [Route("")] public IEnumerable<object> Get() { var identity = User.Identity as ClaimsIdentity; return identity.Claims.Select(c => new { Type = c.Type, Value = c.Value }); } } |
Notice how we attribute the controller with [Authorize] attribute which will protect this resource and only will allow HTTP GET requests containing a valid bearer access token sent in the authorization header to pass, in more details when the request is received the OAuth bearer authentication middle ware will perform the following:
- Extracting the access token which is sent in the “Authorization header” with the “Bearer” scheme.
- Extracting the authentication ticket from access token, this ticket will contain claims identity and any additional authentication properties.
- Checking the validity period of the authentication ticket.
Step 5: Hosting the Authorization Server and Resource Server on different machines
Until this step and if you are developing locally on your dev machine, if you tried to obtain an access token from your Authorization Server i.e. (http://AuthServer/token) and then send this access token to the secured end point in our Resource Server i.e. (http://ResServer/api/protected) the result for this request will pass and you will have access to the protected resource, how is this happening?
One your dev machine once you request an access token from your Authorization Server; the OAuth middleware will use the default data protection provider in your Authorization Server, so it will use the “validationKey” value in machineKey node stored in machine.config file to issue the access token and protect it. The same case applies when you send the access token to your Resource Server, it will use the same machineKey to decrypt the access token and extract the authentication ticket from it.
The same applies if you are planing on your production environment to host your Authorization Server and your Resource Server on the same machine.
But in our case I’m hosting my Authorization Server on Azure website using West-US region, and my Resource Server is hosted on Azure websites on East-US region so both are totally on different machines and they share different machine.config files. For sure I can’t change anything on machine.config file because it is used by different sites on the Azure VMs I’m hosting my APIs on it.
So to solve this case we need to override the machineKey node for both APIs (Authorization Server and Resource Server) and share the same machineKey between both web.config files.
To do so we need to generate a new machineKey using this online tool, the result after using the tool will be as the below: As advised by Barry Dorrans it is not recommend to use an online tool to generate your machineKey because you do not know if this online tool will store the value for your machineKey in some secret database, it is better to generate the machineKey by your self.
To do so I’ll follow the steps mentioned in article KB 2915218, Appendix A which uses Power Shell commands to generate machineKey, so after you open Power Shell and run the right command as the image below you will receive new machineKey
1 |
<machineKey validationKey="A970D0E3C36AA17C43C5DB225C778B3392BAED4D7089C6AAF76E3D4243E64FD797BD17611868E85D2E4E1C8B6F1FB684B0C8DBA0C39E20284B7FCA73E0927B20" decryptionKey="88274072DD5AC1FB6CED8281B34CDC6E79DD7223243A527D46C09CF6CA58DB68" validation="SHA1" decryption="AES" /> |
Note: Do not use those for production and generate a new machineKey for your Servers using Power Shell.
After you generate it open the web.config file for both the Authorization Server (AngularJSAuthentication.API project) and for the Resource Server (AngularJSAuthentication.ResourceServer) and paste the machineKey node inside the <system.web> node as the below:
1 2 3 4 5 6 7 8 |
<system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <machineKey validationKey="VALUE GOES HERE" decryptionKey="VALUE GOES HERE" validation="SHA1" decryption="AES"/> </system.web> |
By doing this we’ve unified the machineKey for both Authorization Server and Resource Server (Only this API in case of Azure shared hosting or any other shared host) and we are ready now to test our implementation.
Step 6: Testing the Authorization Server and Resource Server
Now we need to obtain an access token from our Authorization Server as we did before in the previous posts, so we can issue HTTP POST to the end point (http://ngauthenticationapi.azurewebsites.net/token) including the resource owner username and password as the image below:
If the request succeeded we’ll receive an access token, then we’ll use this access token to send HTTP GET request to our new Resource Server using the protected end point (http://ngauthenticationresourcesapi.azurewebsites.net/api/protected), for sure we need to send the access token in the Authorization header using bearer scheme, the request will be as the image below:
As you notice we’re now able to access the protected resource in our new Resource Server and the claims for this identity which obtained from the Authorization Server are extracted.
That’s it for now folks, hopefully this short walk through helped in understanding how we can decouple the Authorization Server from the Resource Server.
If you have any comment or question please drop me a comment
You can use the following link to check the demo application.
You can use the following link to test the Authorization Server (http://ngauthenticationAPI.azurewebsites.net),
You can use the following link to test the Resource Server (http://ngauthenticationResourcesAPI.azurewebsites.net)
You can check the source code on Github.
As always, great 🙂
Taisser,
I’ve downloaded your sample and tested (with fiddler) the resource server.
Everything works fine.
I’ve seen that the table AspNetUserClaims does not contain any claims but the resource server returns a claim = user.
How can that be possible?
I would have expected the resource server to access the database to verify the credential. That does not happen.
How can the server (resource) know if the client is authorized to access the resource ?
Thanks again for the great explanation.
Alberto
Hi Alberto,
Regarding the claims, that is correct, I’m just setting the claim manually before issuing the token in this LOC, the right way to store them in AspNetUserClaims table.
As I’ve stated before you never store the password on the token. The token is encrypted signed string from Authorization server which sent to the Resource Server and the Resource Server will be responsible to decrypt is using the machineKey. I recommend you to read the post again one more time as this stated clearly.
Taisser,
thanks for your reply.
Regarding claims, yes, that was a silly question. I had realized after I posted my question that you were adding claims in your code.
Regarding my 2nd question, I can understand that my resource server will decrypt the bearer token using the machine key.
I’ve played around with your code a bit.
I’ve seen that I can change the claim passed by GrantResourceOwnerCredentials I can protect my resource using the attribute E.G.: [Authorize(Roles = “Admin”)].
Fair enough, but that would mean the only protection against accessing a specific resource is defined in the token itself.
Am I correct?
Thanks again for your great post.
You are right, the info(claims) in token will be used only to decide if the request is authorized to access the protected resource.
Hi TAISEER,
I tend to build an application using AngularJS and WebAPI, the API will apply Owin for authentication but I need to host both resource server and Authorization server on same machine. I’m wondering if it causes any issue when I host both server in one webserver (e.g: IIS)
Thanks,
Hi Nicky,
No problem at all, if you are going to host them on same server then no need to override machineConfig value on each project web.config, they are hosted on the same server.
Wonderful stuff, thanks very much.
I too would like to host authentication and resources on the same server, but different apps. Is there anything else I need to do, apart from what you’ve described in your post? Protected controller methods from the authorization app always work fine, but I get 401s from the resource app. When I check the authorize filter I derived I notice that Principal.Identity.AuthenticationType is always null in the resource app. This doesn’t seem right to me.
Once again, thanks!
Even though the sites are on the same server once I added machine keys everything worked as advertised. I would imagine there’s something I can do with auto generated machine key settings in IIS, but since this works I’m a happy guy.
Thanks again.
You welcome Louis, happy to help.
Please don’t use random web sites to generate a machine key. It can be dangerous – machine keys should be know only to you. Instead we give you a nice powershell script in a KB article – http://support.microsoft.com/kb/2915218#AppendixA
Thank you Barry again, all has been updated. This information is buried in MS knowledge base articles.
Great stuff – excellent – thanks Taiseer!
You are welcome Steven, thanks for taking the time to read it and comment 🙂
Wouldn’t a signed JWT make more sense as your access token? that way you could verify it came from your authorization server without needing to share any private keys.
Thanks Betty for your comment, I’ll consider checking JWT tokens.
Hi Betty, I agree with you, I’ve blogged about this today http://bit.ly/JWTAPI, check it when you have time and let me know your feedback.
Hi Taiseer,
Nice stuff here. Why not write a complete book on Angular, MVC WebAPI _ Security. You have a way of making complex things sound simple and might help a lot of guys out there
Hi,
Thanks for your compliment, maybe I’ll write small e-book covering those topics 🙂
Thanks for another fantastic article… you’re really providing some great insight in a relatively sparsely documented topic.
Could you perhaps demonstrate how your resource may need to query the authorisation server directly.
For example in OpenID Connect there is a userinfo endpoint which has the ‘profile’ for the user.
The use case I’m considering is the user Authenticates and retrieves a valid access_token from the auth server and then now queries the API server to retrieve the full ‘user profile’ which would then be persisted client side in Angular.
I would expect the Resource Server to somehow take the ‘access_token’ which was used by the requesting client and create a new request direct to the auth server’s userinfo endpoint.
It’s the plumbing of this process that i’m struggling with….
Thanks for your time!
Hi Galen,
I didn’t get the scenario you are asking for 100%, but currently the Auth Server accepts the access token too, so you can use it to get profile data which resides on Auth Server not the Resource Server.
If this didn’t answer your question please elaborate little more 🙂
Thanks for taking the time to read and comment.
Another great article! And thanks for being active in the comments too! Would you consider doing an article for the best ways to publish this tutorial to Azure?
Hello Aaron, glad it was useful, it is pretty straight forward, it is like you are publishing to local iis, you can check this tutorial http://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-get-started/
One of my nightmare you have explained it so nicely. I am a fan of your explanation.
Glad it was clear and useful 🙂
Taiseer, Firstly I’d like to say thank you for an excellent set of article written in a clear and easy to understand format.
The issue I am having is that the decoupled resource is still accessible even after the bearer token has expired.
I first though the issue was with my coding, but I have downloaded the latest sample code from Github today and the issue also exists here.
After the time for the token expiry has lapsed http://localhost:26264/api/orders return authorization denied as expected, but
http://localhost:47039/api/protected is continuing to return the data?
Regards,
Ashish Verma
Thanks for reporting this, you are correct there was a bug and its fixed now, please refer back to step number 2 and read the “Important Note” section where I describe why the bug took place and how we fixed it. Thanks again. I tried to find an online identity for you to refer for it on the post but there are many “Ashish Verma” 🙂
The best-ever tutorial on this subject – you rock Taiseer!
I am experiencing exactly the same issue as Ashish, even after checking both versions of “Microsoft.Owin.Security.OAuth” on the Auth and Resource servers. But both are on v3.0.0 though, not v2.1.0. Should I “downgrade” both to v2.1.0, or perhaps it’s a caching issue. Or any other ideas?
Hi Nic, glad you liked all the series.
Well I’ve tried it with version 2.1.0 for both the resource server and the authz server. What you can try is to check in the resource server if the “ticket.propertis” property is filled with expiry date. You need to unprotect the token to get the ticket using the code below:
//string token = “”;
//Microsoft.Owin.Security.AuthenticationTicket ticket = Startup.OAuthBearerOptions.AccessTokenFormat.Unprotect(token);
I tried again using your code suggestion but now everytime the expiry date was correctly filled with the expected values. And this was with using v3.0.0 of Microsoft.Owin.Security.OAuth on both Auth and Resource server.
So for some strange reason I could not replicate the problem. Perhaps it was cache of IIS Express or Postman, I don’t know, or perhaps probably a “picnic” problem – Problem In Chair Not In Computer :).
But I’ll nevertheless continue to monitor it if time permits it and let you know if I find something. Thanks again for your help!
Correct me if I am wrong but it appears though the key that is generated is an AES symmetric key. The same key is used by the OWIN OAuth middleware on the resource server to validate the token. Is there a way to use an asymmetric approach here instead (e.g. x509 certificate)? My concern is that if someone gained access to your web.config on the resource server and got the newly generated machine key and they understood the format of the token they would have the ability to generate valid tokens that would provide them with access to the resource server. A x509 / asymmetric approach mitigates this concern by only providing the resource server with the ability to validate via the public key and not sign (i.e. create valid tokens). Does anyone else share this concern? If this is possible can you also provide guidance on how this might work?
You are correct, maybe you need to consider using JSON Web Tokens then.
Thank you for your reply. Can you explain how we may be able to make use of JSON Web Tokens? If it just a configuration option our is it all custom code? What token format is currently being used here? We are considering building our own Auth Server and this is one of the remaining gaps that we have.
Thanks in advance
Andrew
Hi Andrew, I’ve blogged http://bit.ly/JWTAPI about using JWT tokens in ASP.NET Web API and how we can use them to decouple Authorization server from Resource server, check and let me know your feedback.
Thanks for the extra blog post, it explains it all very well.
You swapped to JWT but still with a shared symmetric key.
Like Andrew I’m looking for a asymmetric approach (with x509 for example).
I think your code can be changed with some tweaks to asymmetric right?
Hi Job,
You can look on ThinkTecture Identity server where Dominic uses x509 certficates
Taiseer,
One more request :). Will you mind to include Group , Role and permission features as mentioned here (Identity2.0)
http://www.codeproject.com/Articles/808903/ASP-NET-Identity-Implementing-Group-Based-Permissi
Tried to implement the same in your sample code and had to spend hours with no luck. 🙁
I will consider this, currently working on another nice post about Web API and TFA. Keep tuned 🙂
Hi Taiseer,
Just thought I would let you know….. I would also appreciate it if you could extend your demo app to include role based authentication.
I’ve got things working with the [Authorize] attribute, but I don’t know how to implement [Authorize(Roles=”Manager”)] etc.
Any help appreciated.
Regards, Paul
Hi Paul, I will do my best to blog about this in November, hopefully I wont be that busy, so keep tuned.
Hi, I miss this post too!
Subscribe to my blog to stay tuned 😉
Hi Taiseer,
Thanks for the response. This would be a great help to me.
I look forward to you November blog.
Regards, Paul
Hi Taiseer,
Great article, was very helpful. Thank you so much!
Here I have a situation. Our Authorization Server is implemented in JAVA. We have two resource servers one for JAVA endpoints and the other for Web API endpoints. All are hosted on different machines.
Both of these Resource Servers have to interact with Authorization Server to get authenticated and receive access token.
I have to work with Web API Resource Server, I am making a request from my angular app to get access token to Authorization Server (implemented in JAVA), I have got the access token then I am making a request to my Web API Resource Server with this access token. Here I am not getting authenticated.
I have these questions:
1. Do we need to implement both Authorization Server and Resource Server in same technology. I mean both should be implemented in either JAVA or .NET only? In my case access tokens are being generated in JAVA platform and have to be consumed in .NET (i.e Web API)
2. If we share machineKey to both these servers (JAVA- Authentication Server & Web API- Resource Server) as you mentioned in Step 5. Would that work for me?
3. In token authentication, is there any platform dependency? I mean, if we generate access token in JAVA, can’t we consume it in Web API OWIN?
Please suggest a soultion for me! Thanks!
Hi Taiseer,
Did you get any chance to look into my post? Waiting for your reply!
Hi Joy,
Well I believe it will not work like this way directly, you need to unify how the tokens are generated (protected) Web API use by default DPAPI (Windows Data Protection) to protect the ticket and issue the token, so all you servers should conform to same data protect mechanism so this token can be understood by all your servers.
Another option you might consider is to use JWT (JSON Web Tokens) for all your servers, didn’t implement it before but there is libraries for this.
Hope this answers your question.
Hi Taiseer,
Thanks for your reply.
But how OAuth bearer tokens using OWIN are different from JWT.
Hi Joy, I’ve blogged http://bit.ly/JWTAPI about using JWT tokens in ASP.NET Web API and how we can use them to decouple Authorization server from Resource server, I believe this will solve your issue if you have resource server built in different technology other than .NET. JWT is standard so it should work. Check it and let me know your feedback
Hi,
thanks for the great article. Are you able to look at the question I posted on Stackoverflow? This is the link:
https://stackoverflow.com/questions/26458785/i-get-authorization-has-been-denied-for-this-request-error-message-when-using
I have setup a very simple sample and am able to get a token from the auth server but I get an “Authorization has been denied for this request.” error message when attempting to do a GET against a protected resource in another VS 2013 solution.
Can you please let me know what I may be doing wrong here?
Thanks,
Andrew
Thanks for responding to the question on SO. I just had another question that I posted there too. I am running the Auth and Resource server in 2 different VS 2013 solutions and I still get this error message. Please let me know if you have any other suggestions.
Taiseer,
Another great article. Here is my question. Following your posts through, I have added the code for using external authentication. I see that I can still use the de-coupled auth server with access tokens that have been created using the external login path? i.e. Extenrallogin, then create a local access token from the external token.
I assume that my clients will have to know to authenticate against the authorization server and then make calls to the url for t he resource server?
Bob
Hi Bob,
You are correct, all the external authentication will go to the Authorization server, and once client has local access token he can send it to the resource server.
Taiseer,
So, Thanks to your excellent articles, I have a working authorization server that is de-coupled from my resource server.
I have a couple of housekeeping questions. I have deployed both my authorization server and resource server to Azure. Next I want to deploy my front end application to azure, so that all three of them are there. Currently, my front end application is the Angular JS application developed during your tutorial.
My questions are this:
1) Is there an easy way to change the URL’s for the authorization and resource server in the Angular JS application when it is deployed to Azure? It needs to point to localhost on my development machine and point to azure when it is deployed.
2) How do you handle the external providers so that you can authenticate in development and in azure after the deployment? For instance, at Google, you have to set two (2) URLs that point to the application that will be authenticating. I am not sure if it is better to update google so that you can test actual site or if I should create two clients at google and have one point to azure and one local and then change the client id and secure token during the deployment.
Any thoughts would be appreciated.
Hi Robert, you are most welcome.
Please find answers to your question:
1 – well currently I’m doing this manually like your case 🙂 but you can use task runner such as gulp to help you switching those files (dev JS files, prod JS files) automatically, please check my post AngularJS with touch of GulpJS and check the comments section where this has been covered.
2- I think it is better to create 2 clients, one for Dev and one for Prod. but do not quote me on this and check SO, I’m sure others faced your issue before, if you find better answer please share it here.
Hope this answers your questions and good luck in your project 🙂
Hi Taiseer,
Thanks so much for the fantastic tutorials. I am using them to do something very similar but instead of the Resource Server being a Web App, I want it to be a console application. For the life of me I can’t not get it working using the Owin Self Host i.e. boot up a Web API endpoint at localhost:9000, host it as a resource server, ask the Authentication server for a token and then use it.
I get the Access Token 100% of the time, it is only when I go to use it within the Console Application using Owin Self Host that it never is able to authenticate. I have the machine key within the app.config of the Console project, I am using the exact same versions of all the nuget packages that the Web App Resource Project is using but it never gets authenticated.
Any advice would be really appreciated!
Thanks,
– Tim
Hi Tim, happy to find my posts were useful 🙂
Well the Web API OWIN self host doesn’t use MachineKey for protection, this is valid for IIS (System.Web) check this post.
Now my recommendation is to use JWT tokens when you can decouple the servers and use another format for tokens, please refer to my other blog post which shows you how you can implement this.
The JWT tokens are signed only, so do not store sensitive data on them.
Let me know if this helps.
Hi Taiseer,
As mentioned before, thanks for a great series of really helpful articles. I’ve followed them through to the last (decoupling) and am having a problem, which I think may be due to running the separate auth and data services in web workers/webApi projects. Where you’re referencing web.config, I’m using app.config, for instance. Everything works fine up to the point of decoupling, where the protected controller returns “message”: “Authorization has been denied for this request.”.
I’m using the same machine key in both app.configs (despite running on the same machine, but I have also tried it without this setting and the same result). It will be pushed to Azure and possibly separated, so I think it is best to use this machineKey.
I have each worker running on its own port and I have checked the versions of OAuth (both 3.0.0.0). VS is running in administrator mode, if that means anything. I’ve run out of ideas, so wonder if you can point me at anything that might help?
Thanks in advance!
Toby.
Hi Toby,
Your Web API is self hosted or IIS hosted? If it is self hosted then the decoupling post will not work in your case, there encryption algorithm in self host is different than IIS which uses the mahcineKey. Please read this SO question I’ve already answered.
Why you do not consider issuing signed JSON Web Tokens instead of the default tokens? With the JWT approach you can decouple AuthZ server/resource servers regarding the hosting platform, you can read more about this in my last blog post.
Hope this helps and let me know your thoughts about it.
Lol, you’re always one-step ahead! Thank you very much for this advice, I would have spent hours and hours figuring that out. I’d looked at JWT briefly, but thought I could get it working like this (it’s self-hosted, by the way).
So is it correct that I can use the approach I’ve taken (your articles 1-5) in decoupled workerRole processes (i.e. without IIS) as long as I use the JWT approach?
I’ll go through that article now, thanks again 🙂
Hi Toby, JWT should work with Self Host because you are controlling everything even the signing algorithm, I believe it will work across different platform (i.e. the AuthZ server is built using Java and the Resource server is built using .NET) because you are sending JSON object and the signing algorithms should be the same and produce the same hash among different platforms. Let me know if this works at you end.
Good luck.
Hi Taiseer,
You’re absolutely right, it works fine 🙂 I actually prefer this way, now I’ve got my head around it. More control and not tied to MS stack (at last). Brilliant!
Thanks again,
Toby.
Hi Toby
Be lenient on MS 🙂 the new stack especially with ASP.NET vNext will be amazing, they are changing and being sooo open.
Glad it worked at the end 🙂
having a question, when does it call the resource server and where does it call the resource server?
Can I integrate it back into the WebApi?
Hi, can you elaborate little more? Didn’t get your question.
Hello Taiseer,
I’ve removed the authorization server from the solution? DO i still need this for the dynamic claims from the database?
Or a other questions, if I need how can I integrate the authorize server together with the resource server?
How did you remove the Authorization functionality from your solution? How are you going to authenticate the user? Please read again my post about decouple the Authz server and the resource server to know the responsibilities for each one. You can combine both in single project but you can’t remove the functionality for one of them.
You;ve somewhere a tutorial or link which I can follow or how I can integrate them together?
Part 1 and 2 of this series have them together, please read post again slowly and analyze them because I feel you are lost and the topic is simple.
Hi Taiseer,
Good call, you’re right about .Net opening up, that’ll be massive! It’s a good time for C# and MS in general 🙂
Cheers for all the help.
Toby.
Hi Taiseer,
I loved your series it is so informative,
But could you please guide me to authenticate from a separate MVC 5 application not angular, i am pretty new to this, we have a separate authentication server but i need to authenticate the Asp.net MVC 5 web client app with tokens issued from the separate authentication server
Thanks a lot 🙂
Hi Fahd, I guess I’ve seen a SO question which answers your exact case, I do not have access to the URL now but check it there and let me know if you need further help.
Thanks for your reply, I searched a lot in the subject and I will look for the SO question, can you help me about what terms could assist in the search for the right thing
Thanks
Hi Taiseer,
When I access an [Authorize] endpoint and the middleware says my access token is expired and rejected my request, is it possible to get a new token with my refresh token automatically under the hood? I don’t want users re-login manually everytime after the access token is expired.
I am thinking of these steps:
1. client receives an “unauthorized” response from the protected endpoint on the resource server
2. client sends a request with the refresh token to the authentication server to get a new access token
3. client receives a new access token
4. client sends the same request to the protected endpoint on the resource server
Please advice if this approach is viable. Thanks.
W.C.
Hi, yes this is the typical scnario to use the refresh token grant, which is obtain new access token silently without asking the user to provide his credentials again. So implementing this depends on the front end application you are building against your API, for example if you are building AngularJS app you can check Nikolaj implementation for automatic token refresh, for other platforms you need to follow the steps you just outlined.
Hope this helps.
Great series. This will be a great help for us.
We also need to add support for confirmation emails and password reset using the verified email address. Have you thought about adding those? I saw some support for it with the MVC 5 template, but some of the implementation is hidden. Instead I think it would be better to use your approach of showing step by step how to build out the necessary features.
Hi Brian, thanks for your comment, you are right you need to refer to this great post by Rick Anderson inorder to implement registration email confirmation and password forgot and reset.
I’ll consider doing step by step post to show how we can use those features in ASP.NET identity.
Cool, sounds good. We’re using your code as the base of a new system we’re writing. I’ll shoot you a note when we have the email additions to run them by you.
I had another interesting thought. We have some node.js code that we’re starting to right. I wonder if we can set up the node.js code as a resource server and have it use the C# based authorization server. The end environment would be a C# auth server with heterogeneous C# and node resource servers. Any thoughts? I know some pretty smart node guys that also have some C# experience. I wonder if we could get this working.
Hi Brian you can do this by using JWT tokens, so the authorization server will issue JWT tokens which is standard token format and the resources servers built with nodejs will be able to understand those JWT and parse them easily, you can read my detailed post here which shows how to configure AuthZ server to issue JWT.
Wow you are the man! Tried to follow and implement the IdentityServer3 project and failed. This tutorial is way more intuitive and straight to the point!
Glad it was simple to implement, keep tuned for next Identity posts!
Taiseer I have two different projects one mvc based and other web api now i want that when I am going to register the new user the mvc sends data to web api and web api will create user for mvc and also generate token till here it is working fine but i need the web api should return token to mvc and also login automatically please suggest what to do
I can’t understand the whole concept u want to implement here, but if you are using MVC then you need to think of cookies authentication too.
Hello Taiseer,
Thanks fo the great article:) I was wondering if it’s possible to remove context, owin & authRepository from WebAPi project and make it in a separate project So we can use dependency injection and three layer architecture… I’m trying to apply this in your source Code but with no sucess. Tahks again for your useful post.
Hi When we are using fiddler it is working fine but in case of application executing from local host, it is throwing an error for cross domain origin. please help to resolve this.
You are not configuring CORS correctly, check how it is done in the first post and the third one.
Hello Taiseer
Your article was wonderful and simple. Thanks for the detailed article. I want your views on a confusion i have now. Using your implementation I have an authorisation server and i have a resource server (some kind of inventory web api) and now i want a mvc application(possibly multiple mvc and android apps) to authorize with auth server and use web api to list items in inventory. now each mvc application and android application will be issued their own client_id and secret so if i was to use client credentials flow to obtain token from auth server then resource server(web api) would not be able to decrypt the token because it only has its audience secret.
What am i doing wrong here? am i trying to use resource server in a wrong way? what are your views?
Hi Gupreet,
I can’t understand your question clearly, if you have MVC application the I recommend you to use cookies not tokens, tokens are good for JS apps and mobile applications, unless you want to using httpClient library in your MVC app to issue requests.
I might be able to help more If you can elaborate little more about your question. Tried to draw a diagram for your scenario but I can’t understand the whole image.
Hi Taiseer
Thanks for the reply. The situation is that i want to use an identityserver/authorisation server for multiple web apis
So i have started with one web api which will be holding inventory of things. So now i have an authorization server and a web api (resource server). Lets say now i want 2 mobile apps to be able to use my inventory api and also i want to issue a client key and secret to each mobile app to use my api because i dont want just any mobile app to use my api. so now i am guessing these mobile apps are not counted as audience, if so then it means that client key and client secret etc for these apps are not held in AudienceList collection or is it. but in any case now we end up having key/secret pairs for resource server api and for mobile apps. but mobile app will get a token from auth server and jwt token will be ciphered using secret issued to mobile app (or am i wrong here?) if i am correct this would mean when mobile app passes access token to resource server it would not be able to decipher the token because it has a different secret issued to it. so what part of my understanding is wrong here ?
Could you please check this comment, someone facing your issue, hope this helps
Two things.
1. Since you have separated, Auth and Res server, let it reflect in your source code. I missed the part where you said, you are leaving ordersconroller in Auth server. Had to really bang my head, why the heck it is there. It appears you left it there so that your prior articles work. It would be better if you remove it and make it clean.
2 How to configure which claim has access to which resource? Another post or am I missing something? At present your have only one protectedcontroller with one method. If i have more methods how to say which is limited to which role with out doing if condition? Can it be done as an atribute? Recommed this? http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/
Hi Rakesh,
1 – Well you need to read thoroughly then 🙂 It is hard to re-factor the code and then come again and rewrite the starting posts.
2 – This is about roles based authentication or controlling access using claims, keep tuned on my next series as this should be covered. And yes you can depend on writing custom AuthZ attribute.
Thank you
About 2, “This is about roles based authentication or controlling access using claims”, which one is it? Roles or claims?
You can use the one that fits your business needs, Roles authorization is fine if you have limited number of roles and they will not change too much. I will be covering this in the next post.
very useful series of articles, thanks. is it possible to decouple if you want to self host both the resource server and the identity provider? thanks
Sure, you can do this and I recommend you to use JWT tokens instead of this way as this post
Hi Taiseer,
I trying to generate machine key. When i run the script in Powershell i get no output? Do you have any idea why?
Thanks,
To be honest no 🙁 but are you facing any specific error that might help in troubleshooting the issue?
Hi Taiseer,
I am not familiar with powershell, so what i did was i copied the script from the KB 2915218, Appendix A site and saved as .ps1 (which is powershell extension I believe), then i open powershell move to the location of the saved file and type this “./Generate-MachineKey -validation sha1” and press enter.
Am i doing something wrong?
Thanks
To be honest I have no clue why is this happening 🙁 Stack Overflow is our friend, so check there 🙂
I post a question on Stackoverflow.com and i got a correct answer. I have to load the file first before run it. Rookie mistake.
http://stackoverflow.com/questions/28846194/generate-machine-key-using-power-shell
Thanks
Glad it worked 🙂 Thanks for sharing the answer!
Hi Taiseer, I am trying to access Protect resource via angularJs but I get 404 because it uses authorisationserver (http://localhost:26264/) rather than resourceserver (http://localhost:47039/), what can I do to make work.
I manage to access Protected controller via Postman directly.
Thanks in advance
Greate guide, awesome work, thank you for this, and I’m eagerly anticipating last post in your other ‘series’ – ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1
Just wanted to point out few small things, consistency with quote style-ing and other little things, would be nice if you used IIFE-s in angular specific files to prevent some unnecessary global variables and global namespace pollution. John Papa approaches this very diligently, https://github.com/johnpapa/angular-styleguide , ik I’m probably nitpicking here, but just trying to drop some positive criticism.
Really grateful for posts and blog in general, already recommended it to friends.
Keep up the good work!
Thank you for your comment, appreciate your feedback and I agree with you the Angular App code can be optimized for sure.
Taisser,
So, I have followed all 5 steps and I have a fully functioning Authorization server, a Resource server, and a web site. From my web site, I can successfully authenticate through the Authorization server using Google and make authenticated calls to the Resource server to get data. It all works great.
My next step, is that I have an iOS native application (I also have a second Xamarin Forms application) and I would like them to be able to authenticate with my Authorization server and access the resource server. Do you know of any articles or guides to help with that?
At first I was thinking that I could just have the iOS app do what the web site does, but the iOS app does not have a callback URL like the web site does (In your example you have the callback coming to authComplete.html).
Any pointers, links, or suggestions would be greatly appreciated.
Bob
Ho Bob,
You need to define new client for you new apps (iOS and Xamarin) I do not have experience in building mobile Apps using Swift but I guess once you need to authenticate with Google you will open a web view to do this, and from there the app should be able to access website and get the access token from the URL fragment, I’m not sure if this is doable but I remember that someone replied to one of my SO answer and he was able to do it.
Hi Bob,
Have a look at the different grant types.
The default flow used by webbrowsers is “code”, who requires a redirect url.
A native app can use the “token” grant, this uses no url redirect. In this flow the token is returned as content response to your POST request.
I’m sorry, I’ve mixed up the grant and repsonse_type.
Check out this like for your use-case http://tutorials.jenkov.com/oauth2/implicit-request-response.html
great article and series!
question though. our company it wanting to have an enterprise AuthServer to manage all our users, claims, token, etc. so how could you go about this? do we need to modify the entityframework.identity dbschema and logic to build in an applications concept? also, we would like to use SSO
any ideas would be great!
Ho Marco,
If you are looking for full featured AuthZ server which supports all OAuth flows and written by identity experts then my recommendation is to check ThinkTecture Identity Server V3. It is free open source project.
Hope this helps!
thank you i’ll check it out!
Hi Taiseer,
Big fan of your articles – I needed some guidance with a extension to what you have covered in this article. My stack includes AngularJS, ASP.NET MVC and ASP.NET Web API. AngularJS is hosted under a MVC project. The login needs to call a Authorization API that would return a token to the client side AngularJS and using the interceptors will attach the bearer to the header. For every Resource endpoint API request from AngularJS the token would be passed and the API would provide the necessary data. There is also a scenario where the AngularJS would call a Razor template. How does the token get validated for the MVC controller that has the Authorize attribute?
Thanks,
Sidd
Hi Sidd,
Well I’m not big fan of mixing between Web API and MVC authentication where Web Api uses bearer tokens and MVC use cookies, the Authorize attribute in your MVC accepts an authentication cookie not a bearer token, once you hit the MVC controller you are receiving 401 status, right? What is the www-authenticate response header value?
Thanks Taiseer for a quick response. The reason I am using ASP.NET MVC is because we have very complex dynamic screens. What I am trying to achieve is have AngularJS hosted inside a MVC app. AngularJS will call the WEB API project for all service calls, and there are multiple separate Web API projects. Few of the UI views have complex dynamic templates that would need to call the MVC Razor templates (The data for dynamic manipulation cannot be pushed to client side because of the security reason).
You are correct the MVC controller returns 401 status code. Let me know if you have any suggestions regarding any workaround around integrating the authentication between API (token based) and MVC (cookie based) apps.
Hi Sidd,
Please check the VS 2013 ASP.NET Web Project template with individual accounts checked as the boilerplate code contains cookies and bearer tokens authentication.
Hi Taiseer,
Excellent post! I have slightly different requirement and hoping you can help me with. My org has its own authentication server. I would still like to keep the resource server decoupled from the authorization server. How can I integrate my org’s authentication service with the authorization server? Any input would be appreciated!
Thanks,
Bobby
Hi Bobby, this depends on how your organization built the AuthZ server, you might be able to use clients secrets, certificates… So I have no answer here as it depends on org. Server.
For a few hours I tried to apply this on existing resource application but was getting “Authorization has been denied for this request.” whatever I do without finding a way to debug it, I ended up creating new empty project and installing everything as in your guide and I still get the same error… Finally in a desperate attempt I added a machine key in both config file and it’s working! Both application on the same machine but it didn’t work without explicitly define the key in both web.config files.
Hope this may help someone else few hours of trying to get it work.
Thanks for the great posts
You are welcome Islam, but that is strange, what IIS are using? IIS express or 7.5?
Great solution, however when I try to debug the Owin Startup does not seem to get called, so when I try to register or log in the api and token endpoints are not available. Am I missing something when debugging in VS?
Hi Paul, make sure you are referencing the assembly “Microsoft.Owin.Host.SystemWeb” and make sure you are naming the class as “Startup” other wise you need to attribute it with “[assembly: OwinStartup(typeof(FULLNAMESPACE.Startup))]”
Hi Taiseer
First of all, great articles, read through this series from last year, as well as the series from this year (“ASP.NET Identity 2.1 with ASP.NET Web API 2.2”).
I’m new to OAuth, and fairly new to ASP.NET Identity. I have used it in an MVC app with cookies, and now implementing in WebAPI with Bearer Tokens.
We have a working solution based on your articles, which validates clients and uses refresh tokens. Busy implementing the role based stuff as well. What we have is an MVC app as a front to the WebAPI. The WebAPI is going to be consumed by other things as well such as native mobile apps. We can’t at this stage implement a SPA such as Angular for the front end, and so we are using MVC.
My question is, how can I utilize ASP.NET Identity in the MVC application, which deals with the authentication and authorization from the WebAPI? This is so that we can get the out the box functionality of securing controllers and actions within the MVC app. I’m a bit confused as to whether I should be implementing a custom third party authentication provider (such as the Google and Facebook ones included), or if my MVC application should be a resource server (if possible). Refresh tokens and client validation needs to be supported.
Appreciate any advice.
Regards,
Greg Schroder
Great article and great example.
Everything works except for one thing. When I access the protected api it gives a message Authorization has been denied for this request.
I am passing Authorization header with the value of Bearer
I have updated the packages/references in Authentication and resources projects to be the same. I am using 3.0.1 version.
Is it compliant?
Hi Taiseer
I thought I posted here last week but it seems it did not go through, so here goes again…
First of all, great articles, very helpful with ASP.NET Identity.
I have an MVC site fronting a WebAPI secured by ASP.NET Identity. I’d like to use ASP.NET Identity on the MVC layer as well, which in a way duplicates all the authentication and authorization details coming from the WebAPI. This will allow the usual securing of the MVC Controller and Actions etc.
The WebAPI is utilizing OAuth bearer tokens, along with clients and refresh tokens (from your other posts). What I’m not sure about, is should the MVC be modelled as a resource server, or should I be developing a custom authentication provider for ASP.NET identity?
Note that all logic is within the WebAPI, and the MVC app uses client proxies to call the RESTful services. Currently our MVC does the auth token calls to the WebAPI manually, passing in the relevant auth details each time. I’d have to manually be setting the principal/claims identity within the MVC this way, in order to gain the benefit of things like the Authorize annotation. I feel there is a better way possibly, using resource server or authentication provider? ASP.NET Identity is quite large, and I am unsure of things such as external authentications,OverrideAuthentication, HostAuthentication etc.
The WebAPI is also going to be utilized by other portals such as native mobile applications.
Regards,
Greg
Hi Greg,
Your scenario is interesting, and to be honest with you especially that you API will support different clients my recommendation will be to consider installing the Thinktecture identity server where you can support both cases easily (MVC app will use OAuth code flow), (Web API will use resource owner flow or Implicit grant).
If you want to keep using the same approach I will look at your MVC as Resource server, but the issue here that MVC apps understands cookies and here you are returning access tokens, so this might be challenging to implement and I don’t have straight answer to it right now.
Hi Taiseer,
Thanks for such awesome tutorials. These helped me a lot. Just need a little help of yours. I want to develop an authorization server which will serve mobile applications as well as MVC applications also. I’m thinking to decouple Authorization server and resource server. Authorization server will be responsible for Account management, Role management, generate email confirmation links, forget password, role base authorization, claim based authorization.
Which sample should I follow? https://github.com/tjoudeh/AngularJSAuthentication or https://github.com/tjoudeh/AspNetIdentity.WebApi
Also Authorization server and resource server will share same database and I want to go with database first approach. Both the examples uses code first model. How I can implement asp.net identity with database first approach.
Regards,
Neeraj
I recommend you to go with the second link, where I use JWTs, this is more standard way and most of what you are asking for is there already.
Thanks Taiseer!! Is there any way I can use database first model with asp.net identity??
You welcome, I didn’t treied it before, check this SO question.
Why am I getting the following error: XMLHttpRequest cannot load http://localhost:26264/token. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:32150’ is therefore not allowed access. The response had HTTP status code 500.
This due to that CORS is not configured correctly on the API, you need to check how I’m setting the “Access-Control-Allow-Origin” header in the response
Very Good Article
Hi,
How can I encrypt the machine key both in the Authorization and Resource servers. As per my understanding, we need to mention the same machine key in both the servers.
https://msdn.microsoft.com/en-us/library/dtkwfdky(v=vs.140).aspx.
You should not encrypt them, those keys are used by the framework, so you should keep them as is without any encryption, you system admin should only be the one who has access to those keys, so if you do not trust them then you should hire someone else 🙂
thanks for the article, it works just fine.
However I do have one small question: Is this an OAuth 2.0 2-Legged Authentication approach? If not what do you suggest to accomplish that?
I think it covers pretty much the OAuth 2.0 2-legged authentication approach, but I would like a confirmation from you.
Thanks again and great article.
Is it possible to implement a refresh token provider on this approach?
I followed the one from the example in AngularJS, but the returned json does not include “refresh_token” key. any ideas?
Really great post, many thanks!
I would like to see more like those.
You welcome, happy to help.
Great post, many thanks!!
So, when I request an access token with a specific user it returns correctly the access token, however if I request again using another credentials it also returns the new access token for the given user.
the problem is that when I’m trying to access the API protected method I get the same user that first requested access.
Do you know why that happens?
This is the code I’m using for adding the claims:
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
context.OwinContext.Response.Headers.Add(“Access-Control-Allow-Origin”, new[] { “*” });
var user = await AuthHelper.FindUser(context.UserName, context.Password);
if (user == null)
{
context.SetError(“invalid_grant”, “The username or password is incorrect”);
return;
}
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
//identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
identity.AddClaim(new Claim(“sub”, context.UserName));
identity.AddClaim(new Claim(“role”, user.Role));
var props = new AuthenticationProperties(new Dictionary
{
{
“as:client_id”, (context.ClientId == null) ? string.Empty : context.ClientId
},
{
“userName”, context.UserName
}
});
var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);
}
I found my problem. Cache. The Output cache seems to be done in another way. Probably it is important to mention this in the article, just a small warning or notice:
If implementing cache be aware that the same claims identity may be returned if cache is not flushed correctly by user.
I guess you find the solution for this issue, some sort of caching at your code. Apologies for the late reply.
Thanks for the great article it helped me a lot. When i was developing both resource n authorization server, i launched them using IIS Express which comes with VS installation. Everything was working fine. My resource app was accepting token generated by auth server. So when i deployed both apps to my localhost on same machine. The resource server was returning 401 and was not accepting tokens. I solved it by adding machine key. Why do we need to add machine key element on single machine? Can you please explain me why it was working fine with IIS Express but not IIS7? Thanks
Hi,
Is there any answer to your problem? I do have the same issue.
I got a 401 message and Authorization has been denied for this request.
Thank you in advance
[SOLVED]
I’ve also got the 401 problem when porting from IIS Express to Local IIS.
The fix was to disable the auto generation of machine key for both web apps (resourceServer, AuthServer) and set the same key.
go to IIS Manager>> Sites>> [YourSite] >> AuthServer>> Machine key>> remove the checkbox “Automatically generate as runtime” for both Validation key and Decryption key.
I had spent almost my entire weekend trying to troubleshoot this and your reply has saved me. Thank you.
Did you do anything else around machine keys? My auth server and webapi are in the same project. As above it works fine in dev but not when deployed to IIS. I think it may a machine key issue and followed the above advice but it has not solved my problem.
Hello,
maybe am i wrong but what is going on when token expires resource server sides. There is no implementation of refreshing tokens on this side. So we might get unauthorized access. I think there is some work to do with UseOAuthBearerAuthentication ?
You need to implement the refresh token grant if your client application supports this, so check this post which will help you to implement this grant
hello,
yes i have already done that. By the way thank you for your great articles. It helps a lot.
In fact i am not using resource server and authorization server in the standard way. I do not want clients to request directly on authorization server (hidden in fact). I wanted them to have to go through resource server and i didn’t want them to receive a non authorized error when in fact they only have to refresh their token.
So i added some code in my custom OAuthBearerAuthenticationProvider in the method RequestToken :
if (ticket.Properties.ExpiresUtc < DateTime.UtcNow)
{
var client = new HttpClient();
var response = client.PostAsync(new Uri(@"http://myserverip/token"), new StringContent("grant_type=refresh_token&refresh_token=my_refresh_token&client_id=my_clientId", Encoding.UTF8)).Result;
//response contains new token
context.Token = //set new token
}
This way the new token is set in the current context and we go through the Authorize attribute without any problem (if we have rights to access the resource of course).
And there is nothing to do on client side except redirecting to login page on forbidden status.
Very informative post. As a little variant to above, what if the Authorization Server is Google APIs, Client is Mobile Phone or a Web Application & Resource Server is Web API 2.0 (OWIN) Server. I have been trying the variant & the access_token generated by Google APIs doesn’t gets Authentication on the Resource Server.
I have posted by question on SO [http://stackoverflow.com/questions/31390740/how-to-use-google-cross-client-identity-on-android-to-authenticate-web-api-2-und]
Could you please put some light on that?
Hi Kunal, I’m not sure if you read this post before which somehow covers your scenario.
Hi Taiseer,
Nice content. So helpful.
By the way I just want to ask on how to force the oauth token expiration. Lets say for example, a client application generates an access token (1 week token expiration) but I want to force the expiration of that generated access tokens. May I know if this is possible? How? Pls help. thanks
Cheers,
Lloyd
Hi Lloyd,
Those generated tokens are called “self-contained” tokens so they contain all the claims inside it including the expiration datetime, so once you issue it there is no way to force expiration or revoke it. If you need to have more control on the generated access tokens then you need to look at “reference” tokens.
I’m trying to port the resource server element into vNext, however I’m getting a 401 denied. Has anyone looked at using the resource server in vNext?
I have followed your series (very good btw, thank you), and I have it working great with fiddler and the angularjs application. However, I am trying to call the API via my ionic mobile application. I am getting a cross domain error, even though the CORS AllowAll is enabled in the API. The error I am getting is the following (in this example I was just trying to point to your version of the API):
XMLHttpRequest cannot load http://ngauthenticationapi.azurewebsites.net/token. Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8100’ is therefore not allowed access. The response had HTTP status code 400.
Is there something different I need to do for CORS since this is coming from ionic?
Thanks!
Bob
Hi Robet,
You can not access the Api http://ngauthenticationapi.azurewebsites.net/token directly from your JS application, because the origin in the database is not configured to accept your request domain which is “http://localhost:8100” Those values should be unified in order to be avoid this error.
I was facing the same problem. I hard coded the “http://localhost:8100” in “AllowedOrigin” property and worked! Be careful with trailing slash…
Bob / Taiseer, did you ever figure out this CORS / Ionic issue? I’m in the exact same boat in my API – akin to the one in this tutorial series – and, ultimately, the ValidateClientAuthentication() method of my implementation of OAuthAuthorizationServerProvider fails to validate the client ID since the OPTIONS request doesn’t pass the same body as the POST we’re expecting.
Hi Brad,
I’m not sure why it is failing with Ionic and it is working with AngularJS app, I need to search this more when I have time, please share your solution here if you were able to fix it. Thanks
I had this issue occur only when I hit the back button once I have logged in to and tried to login again. Strangely it worked the second time I hit the loign button. So the first time I try to login it fails.
The answer here fixes the issue I had and seems to be one way to handle the OPTIONS call being made by the browser.
I would like to know however if there are different cases that we need to handle. As in check if client is permitted access or any other security measures that we need to add to the method to avoid giving access all the time.
Thanks.
Forgot to include the link
http://stackoverflow.com/questions/26614771/owin-token-authentication-400-bad-request-on-options-from-browser
I’m not sure about this issue, but it looks the answer on SO is good, many up votes there 🙂
Hi,
I have two(Primary/Secondary) app/resource servers in load balanced mode. I have to implement OWIN bearer authentication scheme to the resource end points in load balancing mode… Note:- Both Resource & Authorization servers are sharing same servers in load balanced mode ..
My concern is that if a token is generated by primary server by token request and I’m using that token in Authorization header to request resource end point, which may hit the secondary server due to load balancing, then how that token is getting validated in secondary server as it is generated by primary one …
Is this possible ? Need help ..
Thanks,
RK
Hi Rk, I too faced the same issue and finally resolved the issue . Please add the Machine key tag in the web.config file. Than your token will be shared for multiple web servers. Below is the sample machine key. you can generate your own machine key in windows power shell
Great Article!
Thanks!
Can I modify the token on the resource server code??
So, what I want to do is I will encrypt the token which I get from authorization server in my web application and send to the resource server and in resource server it should decrypt the token and use it.
I am able to encrypt the token in my application but I am wondering how to access the token from resource server and decrypt it. Please Help.
Thank you in Advance.
Hi Nani,
Why you are doing all this complications? You do not need to encrypt/decrypt the token. It is already encrypted using encryption keys in maching.config
Hi Taiseer,
Thanks for the reply.
Even I feel it is complicated, but I faced few questions when I implemented this in my project.
Like, once we got the token and now we are making a request to resource with the token in Postman and we are able to see the data in Postman, which seems to be insecure as we are able to see the data in Postman. So we have concluded to follow this approach of encrypting and decrypting the token.
Hi Taiseer,
Let me first start by saying how helpful this article has been to myself with a number of projects using both Angular JS and Mobile IOS applications. It has been my bible for decoupling and has been faultless to now.
Im not even sure if the issue i am having has anything to do with the way i have implemented your code, but i am getting issues in Azure, in the same Australia South East Datacenter every couple of weeks where suddenly i get errors saying:
Exception Details: System.Security.Cryptography.CryptographicException: Key not valid for use in specified state.
I am taking a punt here and think it must have something to do with when i do a deployment to the machine, either the machines MachineKey is not being picked up from the web.config file.
The only way around this is to actually reset all the passwords.
I can confirm we are using the same MachineKey across both Authorization server and the Resources Server.
Its getting to the stage where i am about ready to just go and host them both on a Azure VM to save me the issues.
Can i just confirmation from yourself or wider community that Azure does pick up and use the MachineKeys from the web.config file.
Also is there anything i can do to find out if the machine keys are being used, and me creating some endpoint in each of the API projects respectively to return back those keys just whilst i’m trying to get it to work.
Any thoughts would be extremely helpful.
i appreciate any guidance on this issue.
Cheers Robbie Tapping
Hi Robbie,
Apologies for the delay in replying you back, I was traveling!
To be honest I’m not sure how Azure picks up machine keys, but I recommend you to use JWT tokens instead of this approach, please read this post and let me know if it will work for you and find it a better solution for your situation. JWT are becoming more standard way as Beater token scheme.
Hi I had the same situation of decoupling my Resourse from the Authorization Server and i got this excellent tutorial and it covered most of all my requirement but the problem now is ,if i try to access a protected resource from my client and even if i use postman am always redirected to the Login page i cant even see if the user is Authorized or not . I’snt supposed that the Athorize attribute only redirects 401(unauthorised) status to login page and give to authorized request
.
It seems that you are using the VS 2013 MVC template directly and it is configured to issue redirect to login page when receveing 401, try to follow the post again and check how it is configured with the Api only.
Thanks for this amazing tutorial. it was very helpful.
i’m working on mvc 5(not AngularJS) and i use the web api 2 as the authorization sever and the mvc app as the resource server.. How can i handle refreshing token in the mvc app without using ajax?
Hi Mohammed, glad to know that posts were useful
AJAX has nothing to do with requesting refresh tokens, please check this post which might be useful for your case.
Hope it will help!
Thanks so much for that post it saves me a lot of time and effort.
I’m facing a new problem: I configured both servers with the same machineKey, the authentication works fine when i hosted them in the same machine, but when i distribute them it’s not working. where could the problem be?
It works now, it was stupid problem.
The Authorization server’s time is different from the Resource server, it issued an access_token and the Resource server saw it as expired(said it was stupid), i posted it so every one face the same problem know what to do.
Thank you Mohammed for sharing this, yes resource server and authorization server time should be in Sync for sure. Good luck in your project.
Great series. I was able to follow a long and get an auth service running separately from my resource server. However, I have the question how does the resource server know how to validate the token against the auth server? Is it simply not contacting the auth service to verify the validity of the token? The Oauth2.0 spec says that the resource server should verify the token, ideally by contacting the auth service and verifying that the token is still valid. How can this be accomplished?
Thanks again.
How did you get the default data protection to work when hosting on IIS. When we separate the auth server and resource server, the resource is able to consume the bearer token, even though they don’t share a validation key. The token does not seem to be getting encrypted.
Hi,
The resource server and auth server are on 2 different physical machines? There is no want that this could happen unless you share validation key between the two.
The resource server and auth server ARE on 2 different physical machines. We do not have any validation key specified in the web.config files. We even tried specifying a validation key on the auth server and no validation key on the resource server. The resource server is able to consume the token and not give an authorize error. We implemented your solution as is. Is there any thing specific we have to do to trigger the data protection to use the machine keys? It is as if it is completely bypassing any kind of machine key level validation. Any help is much appreciated.
Hi Rekha, Taiseer,
I am also into same situation wherein, I am having resource server and auth server on different machines and I added same validation & decryption keys in machine in each web config. But still token is not decrytped as expected and giving auth error for client on resource server.
Help is much appreciated.
Regards
Robin
Hi Robbin,
Can you make sure that you are using the same Owin versions for both resource server and AuthZ server? I remember facing an issue of not accepting the tokens when the resource server was using a newer version of Microsoft.Owin.Security and Microsoft.Owin.Security.OAuth
I guess there is something wrong on the Startup of the Resource server, if it was attribute by [Authorize] and configured correctly it should always return 401 when invalid token or not token is passed, please check the startup file again.
Thanks Taiseer for pointing this out for version mismatch.
I verified version for Owin.Security.OAuth at first place, but on again verifying, found that it is Owin.Security which is version mismatch.
Matching this version at Rsource and Auth Server, application works good.
Thanks a lot again.
Regards
Robin
Hi Taiseer –
thanks for this very detailed series of articles.
I am new to ASP.NET and now I am already trying to start using ASP.NET 5/MVC 6 – do you plan to update your tutorial to the new versions (it involves significant change to how things work)…? Thanks for any feedback!
Reinhard
Hi, thanks for your message, I’m planing to start new ones once the RC2 is released, I can’t update those as there are huuuuuge changes in ASP.NET 5. It is really anew world 🙁
Hi Taseer,
This is really great series of articles to understand complete flow of Owin Auth.
I need your help on following, I need to implement Auth server and resource server seperately, But it failed when eve after using same machine key in web configs of these files.
AuthServer is a webapp only providing token.
Resource server is a SignalR hub and hub API are protected.
Bearer token is passed using cookies and SignalR communication does not support HTTP headers in case if websocket connection.
Regards
rOBIN
Hi Robin,
Can you elaborate more what it is not working exactly? There are many moving parts here.
Get Article. Thanks.
How do you do unit test with Owin TestServer?
Moving the authorization component to its own server has an interesting side-affect…you can no longer use the “AuthorizeEndpointPath” value in the OAuthAuthorizationServerOptions to tell the system where to redirect when a user needs to login. This value must be a relative path to the existing server but the actual path is somewhere in a different project (where the UI lives). I’ve spent a little time looking around the net for the popular solution but have not found it. I have my own Authentication Attribute that I use in all of my Resource Servers and I believe my solution is to extend that attribute to issue a redirect in the client when the appropriate response is returned.
Does anyone have any advice on this before I move forward?
I did a little more digging and found very little information on this option. However, I did find out I have the wrong interpretation of what it is try to do. I thought it might be part of an ecosystem that would automatically handle someone trying to use a page without being authorized or logged in. I am now using Angular response error interceptors to accomplish this on the client when I get a 401 response.
As far as the “AuthorizeEndpointPath” option, it _really_ is an ENDPOINT and IS STILL VALID as a setting when you separate your auth server from your resource servers. I would love to find better usage instructions for future reference. It looks to be useful for social logins. Here is the best description I found on what it does. Although, not how to use it.
“It is the request path where the client application will redirect the user-agent to obtain the user’s consent to issue a token or code. It must begin with a leading slash (the same as TokenEndpointPath).”
Hi ,
Great sample, I have a problem, when i get a correct acces_token, and i try to consume some resource into the same project where i have created this acces_token , all works fine, but when i try to use this acces_token to get a resource in other project i always get 401.
I’ve put the same machinekey on Authz server and Resource server . but nothing ..
Do you know , what might be happen?
Check the IIS Settings from machine key section, it might be configured to automatically generate encryption/decryption keys.
Thanks this is a really awesome series! I have bookmarked it.
As a suggestion, It would be nice if you could add more details around the setup of the clients table for the refresh tokens. I got a bit lost there.
I have also seen other posts on your site and you are doing a great job.
Thanks again!
You are most welcome, this post covers more about refresh tokens and OAuth clients.
thanks very much for this great topics it’s really well written and helpful.
I have only one question what if we used IdentityServer3 i am not have an experience in that but i read your topics and i understand almost every thing in it also i haired about using ADFS Active Directory and open source IdentityServer3 that’s can you give it the role of authentication so ADFS or IdentityServer3 can be used instead of our implementation of the authentication server is that correct? and i haired that IdentityServer3 is a best solution so is that correct?
Thanks again for your help.
Hello Ahmed,
I agree with you, if you are looking for building STS provider than IdentityServer 3 is the way to go, implementing this from scratch is very hard and can leave you open for a lot of security holes.
Hi Taiser.
I try to generate shorter tokens by choosing shorter AES key length and i general playing a bit with machineKey Values.
To no avail.
Are you sure that the machineKey section is honored in OWIN applications?
Do you know any other Extension points to hand over Encryption and Validation Keys?
Thanks in advance.
Hi Mike,
Did you override those values in the web.config of you app? To make sure that you are working on the correct machineKey values, try to generate a token with certain key, then change this key and try to use this token again, you should receive 401.
I tried this. It really looks like the the keys are not used. I am having the keys in the App.config because there is no web.config when self hosting. It uses OWIN SelfHost. I have these settings in my Unit Test project and the lib which implements the OAuth bits. To no avail.
…
…
Are you aware of any other way to handover theses keys to the OAuth2 Infrastructure?
Hi Taiser. I just found out that this section in the app.config file is disregarded when you use OWIN Selfhost WebApi. It looks like the only way of doing it is implmenting IDataProtector yourself.
Anyway, thanks a lot. Your Blog is a great Resource and helped me a lot.
any progress on this? could you share more on this, I’m facing the same issue even 2 services are running in same local machine with SelfHost mode (OWIN).
Hey taiseer thanks again for this wonderful serie, i followed it and now i want to add role management, so i tried to follow your serie ” ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API ” but i got confused since they are a little bit different . any help ? steps to follow ?
hi Taiseer, does Resource server ever communicates with Authorization server?
How is Authority URL is used in IdentityServerBearerTokenAuthenticationOptions?
What if there is no communication between Resource server and Authorization server?
Thank you in advance!
i think the answer to my own question would be use of Local as Validation mode.
That is correct, and sorry for the late reply.
I get a 401 error. I am doing everything you mention and have assured that all owin references are the same versions. I have set machine keys to be identical (though this is running locally). Does it matter what the value of authentication in the web.config’s is?
It was not clear to me how to use Refresh Token along with Access Token on Resource server…
I mean, Refresh Token will only be used on Auth Server, in order to get a new Access Token. So, if I try to use an expired access token in Resource Server, I will get a 401 error, and then I should get a new access token from Auth Server and send the request to Resource Server again. Is that?
Another point is origin used to request to Resource Server. Is any origin allowed to send request Resource Server, once a valid access token is also sent on Header?
Taiseer Joudeh,
Token generated by Authorization server is not recognizing in Resource server. {“message”:”Authorization has been denied for this request.”}.
Both Authorization and Resource servers are implemented exactly based on your example but still same issue exists.
Any idea why it is not working?
Thanks and Regards,
Raghunath
Hi,
Are you facing this issue after you deployed the solution to IIS or on IIS express? Well maybe the IIS is configured to automatically generate a decryption key, you need to make sure it is static. Check this settings on this URL
Hope this helps.
they may use the OWIN host (selfhost), there’s no web.config, but a app.config, for me, I added the machine key section in app.config, but still rejected with 401
Hello,
You wrote that
“In the previous posts we’ve built the Authorization Server and the Resource Server using a single software component (API)”.
Do you have any links to that post?
Did you use a specific nuget package to implement the Auth. Server and the Resource Server in a single software? If yes, which one?
Best Regards,
Nicolas
Hi Nicolas, the post I was referring to is this one, hope this helps.
Hi Taiser, thanks for all, your posts are very very very useful. Now i’m missing one piece, can you help me?
i succefully created a resource server that uses the authorization server on the same machine with default configuration and also using a generated machine key.
Now i need to use the authorization server placed on a server like http://server1/token and the resource server api is on another server, like http://server2/api/resource, i used the same machine key on both application but how can the resource server application that runs on server 2 know where to validate tokens?
Hi Emanuele,
If I understood you correctly, there is nothing extra you need to do if you shared the validationKeys between the 2 apps, the AuthZ server will use the same keys to encrypt the token and sign it, and the resource server will use the same keys to decrypt it and validate the signature. Is this helpful? If not please elaborate more.
This helped me a lot. Thank you!
You are most welcome, thanks for your message.
Thanks for the posts, they have helped a ton. I am having one issue. Upon separating the Resource and Authentication servers, everything works well except I cannot get any info on the current User in the protected controller. All values are empty strings or null. I am sure I am missing something somewhere. Any help would be appreciated.
Very good article! That help me a lot!!
I deployed the decoupled Authz application and Resource application, and tried to issue a HTTP POST request to URL http://192.168.1.110/Authentication/token and I get 404 answer.
Looked up several comments in your articles that relates to my problem, tried to apply the workarounds but didn’t get success.
Can you help me?
Just to clarify, I’m in the same LAN network of this server. And I also tryed to access with the DNS that I registered for this domain, in this case “http://dev.{somename}.com.br/”.
And when I issue whatever request, to the Resource server or to the Authentication server I get a 404 answer.
For example, instead of your DNS I put mine, which is a valid one:
http://ngauthenticationresourcesapi.azurewebsites.net/api/protected
I was supposed to me get a 401 – Unauthorized , because I didn’t get the token first.
My point is, why in your deploy all things work and in my deploy did not work? Any points I’m missing? Any IIS configuration?
And I’d like to thank you for all your effort you put in this, I followed all steps and get success!! Except when I deployed, lol.
Thanks
I deployed both applications in other server and now it’s working properly! Thank you very much for the thorough article.
How did you solve? i have the same problem
I just deployed both applications in a different server… Each one in separate website in IIS… I think it can be some IIS configuration issue.
This is the best resource I can find online!!! I’m anxiously waiting for the client side. I’m hoping angularjs 2.0 RTM. Thanks so much!
You are most welcome, happy to help
Hi,
I have a different scenario. I’m using an external Auth server (Auth0) to authorize my app (Angular 2) . And that works fine, I get the jwt tokens. but I also need to protect communication between my app and backend (webapi). The auth server is external so I cannot sync the machine key. What would be the best way to handle this?
Thanks
Hello Salman,
If you are using Auth0 then you should not be reading this post 🙂 it is a complete Identity server that does all the Auth/AuthZ magic for you. If you have a special case please contact Jerrie here and he will help you, he is Auth0 customers success engineer focusing on the .NET platform.
Thanks for your time in this serie of excellent articles!
I have one question:
Is it possible to have this Authorization server working with a WCF resource server?
What kind of changes would be needed?
That’s a good question which I do not have an answer for right now, but is it a must to expose REST Api using WCF technology? If I were you I will try to avoid using WCF to serve HTTP Services.
I tried to avoid but the client insisted for unclear reasons.
Anyways thank you, if you have some new information please share 😉
Hi Taiseer,
Congratulation for greate solution and implementation. I used it to implement token based authentication.
We have modular application and every module will be independant SPA. Currently we have to login to every module.
So my question is, how could I add single sign on to this structure?
I am facing with “Authorization has been denied for this request.” as accessing to the resource server.
Authorization Server and Resource server are using the same machine key.
I am using IIS7 to deploy them at: http://localhost:8088/token and http://localhost:8089/api/protected
Please help me
Hello Joshep, Did you override the key values in your application web.config or machine.config?
After add machineKey in Poweshell, my iis express local throw 500.19 error, help??
Hello Taiseer,
Thanks for a great Article and really helpful resource.
I was trying your demo application on azure and it throws “message”: “Authorization has been denied for this request.” for the protected url http://ngauthenticationresourcesapi.azurewebsites.net/api/protected
I generated the Token from here http://ngauthenticationapi.azurewebsites.net/token using
the user id – manishramanan15
Its not working.
I’m not sure what is not working correctly on the demo site, this has been deployed more than 2 years ago, I will check if there is some error.
Sorry for not being clear earlier. The “Step 6: Testing the Authorization Server and Resource Server” is not working it throws authorization error.
Hello Taiseer,
Thanks for the great roadmap!
Could you please advise, is the any possibility to authorize user again within the same AJAX request?
We have separate auth server based on Owin bearer. Once his token expires, we have to handle 401 answer in javascript and redirect him to some authorize controller, where he will get his token again in the cookies. But this ugly redirect crashes UI scenarios, so user ought to do the same operations again.
Hi Pavel,
I think you need to find a JS/AJAX library which queues failed requests then issue them again silently.
Hi Taisser,
how is it possible to configure role based authentication on the resource server.
I have read and followed your tutorial about it and everything works fine on authorization server, but it does not on the resource server?
Thanks in advance
Hello,
Would it be simple, to change the web implementation of Angular to Microsoft MVC?
Thanks.
Hi Ivan,
Well you can do this for sure, check this post which should be useful.
Hi Taiseer,
Thanks for such a wonderful series of articles. I really appreciate the details that you have covered.
I have couple of questions:
1. (Someone has already asked similar question) Shouldn’t there be any linking between authorization server and resource center. Like when a new request is received at resource server shouldn’t it check with authorization server for validity of tokens?
2. (Probably answering this question might answer the previous question too) Is there a way to remove dependency on machinekey tag?
Lets take a hypothetical case. Suppose I have 4-5 different sites (in reality I have only 1 site; that too without authentication 😀 ). Instead of implementing authentication logic on all sites I decide to use authorization server as described in your article. If I understand, I will need to use the same machinekey tag on all sites. Now if any one of my host is compromised then security of other sites will also be at risk. Also lets assume some of my sites are not using ASP.Net stack and instead developed in PHP / Java / NodeJS etc. In these cases we can’t rely on machinekey tag on resource server. So is there a way to have a unique key combination for each resource site and make it generic so that we can use same auth server for resource site developed using different technologies (the way Google and Facebook provide us an API endpoint that we can use to validate the tokens).
While exploring options I could find that OAuthBearerAuthenticationOptions has 2 properties: AccessTokenFormat and AccessTokenProvider, which can probably be used for what I’ve mentioned above. But I’m not very sure how to use these properties and what would be the equivalent code in resource servers. If you know can you share some info about this?
I tried to deploy the Authentication portion to a test sever running IIS 8 but it gives me an error: “No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:9000’ is therefore not allowed access. The response had HTTP status code 500.”
It works on localhost just fine when developing using VS… any hints on where to look?
I updated System.IdentityModel.Tokens.Jwt to version 5.1.2, now I’m having problem to create JwtSecurityToken.
Need help.
Thanks.
Yup I know, there are breaking compatibilities, sorry I didn’t look at it yet.
Whatever you do, do not, under any circumstances go past 4.4 of System.IdentityModel.Tokens.Jwt. It’s completely broken right now and will not work in .NET 4.x except in the most basic of cases and you’ll regret it when you try and revert, it’s a day long exercise in frustration.