Bit of Technology

  • Archive
  • About Me
    • Advertise
    • Disclaimer
  • Speaking
  • Contact

Implement OAuth JSON Web Tokens Authentication in ASP.NET Web API and Identity 2.1 – Part 3

February 16, 2015 By Taiseer Joudeh 327 Comments

Be Sociable, Share!

  • Tweet
  • Email
  • WhatsApp

This is the third part of Building Simple Membership system using ASP.NET Identity 2.1, ASP.NET Web API 2.2 and AngularJS. The topics we’ll cover are:

  • Configure ASP.NET Identity with ASP.NET Web API (Accounts Management) – Part 1.
  • ASP.NET Identity 2.1 Accounts Confirmation, and Password/User Policy Configuration – Part 2.
  • Implement JSON Web Tokens Authentication in ASP.NET Web API and Identity 2.1 – (This Post)
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • AngularJS Authentication and Authorization with ASP.NET Web API and Identity 2.1 – Part 6

The source code for this tutorial is available on GitHub.

Implement JSON Web Tokens Authentication in ASP.NET Web API and and Identity 2.1

Featured Image

Currently our API doesn’t support authentication and authorization, all the requests we receive to any end point are done anonymously, In this post we’ll configure our API which will act as our Authorization Server and Resource Server on the same time to issue JSON Web Tokens for authenticated users and those users will present this JWT to the protected end points in order to access it and process the request.

I will use step by step approach as usual to implement this, but I highly recommend you to read the post JSON Web Token in ASP.NET Web API 2 before completing this one; where I cover deeply what is JSON Web Tokens, the benefits of using JWT over default access tokens, and how they can be used to decouple Authorization server from Resource server. In this tutorial and for the sake of keeping it simple; both OAuth 2.0 roles (Authorization Server and Recourse Server) will live in the same API.

Step 1: Implement OAuth 2.0 Resource Owner Password Credential Flow

We are going to build an API which will be consumed by a trusted client (AngularJS front-end) so we only interested in implementing a single OAuth 2.0 flow where the registered user will present username and password to a specific end point, and the API will validate those credentials, and if all is valid it will return a JWT for the user where the client application used by the user should store it securely and locally in order to present this JWT with each request to any protected end point.

The nice thing about this JWT that it is a self contained token which contains all user claims and roles inside it, so there is no need to do any extra DB queries to fetch those values for the authenticated user. This JWT token will be configured to expire after 1 day of its issue date, so the user is requested to provide credentials again in order to obtain new JWT token.

If you are interested to know how to implement sliding expiration tokens and how you can keep the user logged in; I recommend you to read my other post Enable OAuth Refresh Tokens in AngularJS App which covers this deeply, but adds more complexity to the solution. To keep this tutorial simple we’ll not add refresh tokens here but you can refer to the post and implement it.

To implement the Resource Owner Password Credential flow; we need to add new folder named “Providers” then add a new class named “CustomOAuthProvider”, after you add then paste 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    public class CustomOAuthProvider : OAuthAuthorizationServerProvider
    {
 
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
            return Task.FromResult<object>(null);
        }
 
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
 
            var allowedOrigin = "*";
 
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
 
            var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
 
            ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
 
            if (user == null)
            {
                context.SetError("invalid_grant", "The user name or password is incorrect.");
                return;
            }
 
            if (!user.EmailConfirmed)
            {
                context.SetError("invalid_grant", "User did not confirm email.");
                return;
            }
 
            ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT");
        
            var ticket = new AuthenticationTicket(oAuthIdentity, null);
            
            context.Validated(ticket);
          
        }
    }

This class inherits from class “OAuthAuthorizationServerProvider” and overrides the below two methods:

  • As you notice the “ValidateClientAuthentication” is empty, we are considering the request valid always, because in our implementation our client (AngularJS front-end) is trusted client and we do not need to validate it.
  • The method “GrantResourceOwnerCredentials” is responsible for receiving the username and password from the request and validate them against our ASP.NET 2.1 Identity system, if the credentials are valid and the email is confirmed we are building an identity for the logged in user, this identity will contain all the roles and claims for the authenticated user, until now we didn’t cover roles and claims part of the tutorial, but for the mean time you can consider all users registered in our system without any roles or claims mapped to them.
  • The method “GenerateUserIdentityAsync” is not implemented yet, we’ll add this helper method in the next step. This method will be responsible to fetch the authenticated user identity from the database and returns an object of type “ClaimsIdentity”.
  • Lastly we are creating an Authentication ticket which contains the identity for the authenticated user,  and when we call “context.Validated(ticket)” this will transfer this identity to an OAuth 2.0 bearer access token.

Step 2: Add method “GenerateUserIdentityAsync” to “ApplicationUser” class

Now we’ll add the helper method which will be responsible to get the authenticated user identity (all roles and claims mapped to the user). The “UserManager” class contains a method named “CreateIdentityAsync” to do this task, it will basically query the DB and get all the roles and claims for this user, to implement this open class “ApplicationUser” and paste the code below:

1
2
3
4
5
6
7
//Rest of code is removed for brevity
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}

Step 3: Issue JSON Web Tokens instead of Default Access Tokens

Now we want to configure our API to issue JWT tokens instead of default access tokens, to understand what is JWT and why it is better to use it, you can refer back to this post.

First thing we need to installed 2 NueGet packages as the below:

1
2
Install-package System.IdentityModel.Tokens.Jwt -Version 4.0.1
Install-package Thinktecture.IdentityModel.Core -Version 1.3.0

There is no direct support for issuing JWT in ASP.NET Web API,  so in order to start issuing JWTs we need to implement this manually by implementing the interface “ISecureDataFormat” and implement the method “Protect”.

To implement this add new file named “CustomJwtFormat” under folder “Providers” and paste 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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    public class CustomJwtFormat : ISecureDataFormat<AuthenticationTicket>
    {
    
        private readonly string _issuer = string.Empty;
 
        public CustomJwtFormat(string issuer)
        {
            _issuer = issuer;
        }
 
        public string Protect(AuthenticationTicket data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
 
            string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
 
            string symmetricKeyAsBase64 = ConfigurationManager.AppSettings["as:AudienceSecret"];
 
            var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
 
            var signingKey = new HmacSigningCredentials(keyByteArray);
 
            var issued = data.Properties.IssuedUtc;
            
            var expires = data.Properties.ExpiresUtc;
 
            var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);
 
            var handler = new JwtSecurityTokenHandler();
 
            var jwt = handler.WriteToken(token);
 
            return jwt;
        }
 
        public AuthenticationTicket Unprotect(string protectedText)
        {
            throw new NotImplementedException();
        }
    }

What we’ve implemented in this class is the following:

  • The class “CustomJwtFormat” implements the interface “ISecureDataFormat<AuthenticationTicket>”, the JWT generation will take place inside method “Protect”.
  • The constructor of this class accepts the “Issuer” of this JWT which will be our API. This API acts as Authorization and Resource Server on the same time, this can be string or URI, in our case we’ll fix it to URI.
  • Inside “Protect” method we are doing the following:
    • As we stated before, this API serves as Resource and Authorization Server at the same time, so we are fixing the Audience Id and Audience Secret (Resource Server) in web.config file, this Audience Id and Secret will be used for HMAC265 and hash the JWT token, I’ve used this implementation to generate the Audience Id and Secret.
    • Do not forget to add 2 new keys “as:AudienceId” and “as:AudienceSecret” to the web.config AppSettings section.
    • Then we prepare the raw data for the JSON Web Token which will be issued to the requester by providing the issuer, audience, user claims, issue date, expiry date, and the signing key which will sign (hash) the JWT payload.
    • Lastly we serialize the JSON Web Token to a string and return it to the requester.
  • By doing this, the requester for an OAuth 2.0 access token from our API will receive a signed token which contains claims for an authenticated Resource Owner (User) and this access token is intended to certain (Audience) as well.

Step 4: Add Support for OAuth 2.0 JWT Generation

Till this moment we didn’t configure our API to use OAuth 2.0 Authentication workflow, to do so open class “Startup” and add new method named “ConfigureOAuthTokenGeneration” as the below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
        private void ConfigureOAuthTokenGeneration(IAppBuilder app)
        {
            // Configure the db context and user manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
 
            OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
            {
                //For Dev enviroment only (on production should be AllowInsecureHttp = false)
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/oauth/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new CustomOAuthProvider(),
                AccessTokenFormat = new CustomJwtFormat("http://localhost:59822")
            };
 
            // OAuth 2.0 Bearer Access Token Generation
            app.UseOAuthAuthorizationServer(OAuthServerOptions);
        }

What we’ve implemented here is the following:

  • The path for generating JWT will be as :”http://localhost:59822/oauth/token”.
  • We’ve specified the expiry for token to be 1 day.
  • We’ve specified the implementation on how to validate the Resource owner user credential in a custom class named “CustomOAuthProvider”.
  • We’ve specified the implementation on how to generate the access token using JWT formats, this custom class named “CustomJwtFormat” will be responsible for generating JWT instead of default access token using DPAPI, note that both format will use Bearer scheme.

Do not forget to call the new method “ConfigureOAuthTokenGeneration” in the Startup “Configuration” as the class below:

1
2
3
4
5
6
7
8
9
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
 
ConfigureOAuthTokenGeneration(app);
 
//Rest of code is removed for brevity
 
}

Our API currently is ready to start issuing JWT access token, so test this out we can issue HTTP POST request as the image below, and we should receive a valid JWT token for the next 24 hours and accepted only by our API.

JSON Web Token

Step 5: Protect the existing end points with [Authorize] Attribute

Now we’ll visit all the end points we have created earlier in previous posts in the “AccountsController” class, and attribute the end points which need to be protected (only authenticated user with valid JWT access token can access it) with the [Authorize] attribute as the below:

 – GetUsers, GetUser, GetUserByName, and DeleteUser end points should be accessed by users enrolled in Role “Admin”. Roles Authorization is not implemented yet and for now we will only allow any authentication user to access it, the code change will be as simple as the below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Authorize]
[Route("users")]
public IHttpActionResult GetUsers()
{}
 
[Authorize]
[Route("user/{id:guid}", Name = "GetUserById")]
public async Task<IHttpActionResult> GetUser(string Id)
{}
 
 
[Authorize]
[Route("user/{username}")]
public async Task<IHttpActionResult> GetUserByName(string username)
{
}
 
[Authorize]
[Route("user/{id:guid}")]
public async Task<IHttpActionResult> DeleteUser(string id)
{
}

– CreateUser and ConfirmEmail endpoints should be accessed anonymously always, so we need to attribute it with [AllowAnonymous] as the below:

1
2
3
4
5
6
7
8
9
10
11
12
[AllowAnonymous]
[Route("create")]
public async Task<IHttpActionResult> CreateUser(CreateUserBindingModel createUserModel)
{
}
 
[AllowAnonymous]
[HttpGet]
[Route("ConfirmEmail", Name = "ConfirmEmailRoute")]
public async Task<IHttpActionResult> ConfirmEmail(string userId = "", string code = "")
{
}

– ChangePassword endpoint should be accessed by the authenticated user only, so we’ll attribute it with [Authorize] attribute as the below:

1
2
3
4
5
[Authorize]
[Route("ChangePassword")]
public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
{
}

Step 6: Consume JSON Web Tokens

Now if we tried to obtain an access token by sending a request to the end point “oauth/token” then try to access one of the protected end points we’ll receive 401 Unauthorized status, the reason for this that our API doesn’t understand those JWT tokens issued by our API yet, to fix this we need to the following:

Install the below NuGet package:

1
Install-Package Microsoft.Owin.Security.Jwt -Version 3.0.0

The package “Microsoft.Owin.Security.Jwt” is responsible for protecting the Resource server resources using JWT, it only validate and de-serialize JWT tokens.

Now back to our “Startup” class, we need to add the below method “ConfigureOAuthTokenConsumption” as the below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        private void ConfigureOAuthTokenConsumption(IAppBuilder app) {
 
            var issuer = "http://localhost:59822";
            string audienceId = ConfigurationManager.AppSettings["as:AudienceId"];
            byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings["as:AudienceSecret"]);
 
            // Api controllers with an [Authorize] attribute will be validated with JWT
            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationOptions
                {
                    AuthenticationMode = AuthenticationMode.Active,
                    AllowedAudiences = new[] { audienceId },
                    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
                    {
                        new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
                    }
                });
        }

This step will configure our API to trust tokens issued by our Authorization server only, in our case the Authorization and Resource Server are the same server (http://localhost:59822), notice how we are providing the values for audience, and the audience secret we used to generate and issue the JSON Web Token in step3.

By providing those values to the “JwtBearerAuthentication” middleware, our API will be able to consume only JWT tokens issued by our trusted Authorization server, any other JWT tokens from any other Authorization server will be rejected.

Lastly we need to call the method “ConfigureOAuthTokenConsumption” in the “Configuration” method as the below:

1
2
3
4
5
6
7
8
9
10
11
public void Configuration(IAppBuilder app)
{
HttpConfiguration httpConfig = new HttpConfiguration();
 
ConfigureOAuthTokenGeneration(app);
 
ConfigureOAuthTokenConsumption(app);
//Rest of code is here
 
}

Step 7: Final Testing

All the pieces should be in place now, to test this we will obtain JWT access token for the user “SuperPowerUser” by issuing POST request to the end point “oauth/token”

Request JWT Token

Then we will use the JWT received to access protected end point such as “ChangePassword”, if you remember once we added this end point, we were not able to test it directly because it was anonymous and inside its implementation we were calling the method “User.Identity.GetUserId()”. This method will return nothing for anonymous user, but after we’ve added the [Authorize] attribute, any user needs to access this end point should be authenticated and has a valid JWT.

To test this out we will issue POST request to the end point “/accounts/ChangePassword”as the image below, notice he we are sitting the Authorization header using Bearer scheme setting its value to the JWT we received for the user “SuperPwoerUser”. If all is valid we will receive 200 OK status and the user password should be updated.

Change Password Web API

The source code for this tutorial is available on GitHub.

In the next post we’ll see how we’ll implement Roles Based Authorization in our Identity service.

Follow me on Twitter @tjoudeh

References

  • Understanding OWIN/Katana Authentication/Authorization Part I: Concepts by John Atten
  • Featured Image Source

Be Sociable, Share!

  • Tweet
  • Email
  • WhatsApp

Related Posts

  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4
  • AngularJS Authentication Using Azure Active Directory Authentication Library (ADAL)
  • JSON Web Token in ASP.NET Web API 2 using Owin
  • Decouple OWIN Authorization Server from Resource Server

Filed Under: ASP.NET, ASP.NET Identity, ASP.Net Web API, CodeProject, Web API Security, Web API Tutorial Tagged With: Authentication, Authorization, JSON Web Tokens, JWT, OAuth

Comments

  1. xivsolutions says

    February 17, 2015 at 3:06 pm

    Per ususal, an excellent resource! Thanks for the back link!

    Reply
    • Taiseer Joudeh says

      February 17, 2015 at 4:55 pm

      Thank you John, I enjoy reading your concise posts too 🙂

      Reply
  2. Neil Camilleri says

    February 17, 2015 at 9:18 pm

    Excellent, looking forward to the rest of the series!

    Reply
    • Taiseer Joudeh says

      February 18, 2015 at 10:49 am

      Thanks Neil, glad to know it was useful 🙂

      Reply
  3. Toby says

    February 17, 2015 at 9:22 pm

    Excellent work, as always Taiseer. I’m really looking forward to the rest of this post series. Thanks for your hard work. 🙂

    Reply
    • Taiseer Joudeh says

      February 18, 2015 at 10:31 am

      Thanks Toby, glad it was useful. Roles Authorization is the next post, so keep tuned 🙂

      Reply
  4. Ryan Duffing says

    February 18, 2015 at 4:58 am

    Thanks for the article!

    Reply
    • Taiseer Joudeh says

      February 18, 2015 at 10:28 am

      Glad you liked it Rayan, I’ve received your email and will get back to you soon.

      Reply
      • Ryan Duffing says

        February 18, 2015 at 3:02 pm

        Taiseer.

        Don’t worry about it. I ended up figuring it out. I had a controller on my API side (not my Resources side) that had the Authorize attribute on it. I was getting access denied because I hadn’t set up my API side to use JwtBearerAuthentication like I did with my Resources side. I’m all set!

        Ryan

        Reply
  5. Martin says

    February 18, 2015 at 1:08 pm

    Great article, I am waiting for next.
    Can you send me name or link to software you use to call API requests?…
    This one you show on screens with Request and Response parameters.

    Reply
    • Taiseer Joudeh says

      February 18, 2015 at 1:13 pm

      Glad that u liked it, the Rest client called PostMan, it’s chrome extension.

      Reply
      • Martin says

        February 19, 2015 at 12:45 pm

        Thx.

        Reply
  6. Sam says

    February 19, 2015 at 6:48 pm

    Thank you very much!!!!

    Reply
  7. Walter says

    February 20, 2015 at 11:23 am

    Thank you. Excellent article. Excellent series. Looking forward to the remainder of the articles and seeing that AngularJS app going end-to-end with Web API.

    Reply
    • Taiseer Joudeh says

      February 22, 2015 at 12:45 pm

      Glad it it was useful, thanks for your comment.

      Reply
  8. icconewi says

    February 20, 2015 at 12:03 pm

    Awesome! Waiting for the next post! When will it be aprox…?

    Reply
    • Taiseer Joudeh says

      February 22, 2015 at 12:46 pm

      Thanks for your message, hopefully next week, keep tuned 🙂

      Reply
  9. boliwe says

    February 20, 2015 at 11:05 pm

    I want to tell my thoughts about membership. Asp.net Web Api membership is based on creating a new database schema for users, roles, etc. But if I have already a database(ecommerce,blog) that including users, roles but different schema. In this stuation, Should I need to implement and override Owin OAuth types like Identity, User, OAuth providers, etc.? This is tedious. The Web Api approach is based on creating new database. But in real world, developers are already database. And adaptation should so be easy.

    Reply
  10. Blake Schreurs says

    February 21, 2015 at 12:16 am

    Is there an end-to-end identity server available? Because I’ve been beating my head trying to get all of these parts to work together for days, and I’m getting really frustrated with the whole MS/OWIN stack. This is WAY harder and more complex than it has any right to be.

    Reply
    • Taiseer Joudeh says

      February 21, 2015 at 12:20 am

      You can check the Identity Server v3, open source Authz server.

      Reply
  11. Luis E Leal says

    February 24, 2015 at 2:39 am

    Excellent presentation. Thanks

    Reply
    • Taiseer Joudeh says

      February 24, 2015 at 3:04 am

      Glad you liked it, thanks for your comment!

      Reply
  12. Jeroen Jansen (@JeroenJansen) says

    February 24, 2015 at 1:45 pm

    Thank you very much for this excellent tutorial. Although you explain this complex matter in a very clear and pleasant way, I am not capable to adapt your code in any way. Trying to jump from VB webforms to C# SPA, I will have to use – if that is allowed – your source as a ‘black box’ to handle authorization. Your solution seems to be much better en practical than the current Visual Studio templates.

    Could you please explain how to generate the audience Id and secret in the web.config. I do not know what t do with the ‘implementation’ file.

    Reply
    • Taiseer Joudeh says

      February 25, 2015 at 1:33 pm

      Sure you can use the source code, as well the Audience Id is random string it can be Guid and the secret can be generated as this highlighted code

      Reply
  13. jefferson says

    February 25, 2015 at 8:02 pm

    Simply fantastic , I am eagerly awaiting the next posts , thanks for the tutorials

    Reply
    • Taiseer Joudeh says

      February 27, 2015 at 5:55 am

      Thanks for your message, finalizing the next post so should be published soon.

      Reply
  14. Joost says

    February 26, 2015 at 10:50 pm

    This would be even more awesome if you could also describe how to implement this in ASP.NET vnext. Can’t find anything on that 🙁

    Reply
  15. István Antal says

    March 4, 2015 at 3:32 pm

    Meanwhile, the ASP.NET Identity 2.2 has been released. Any compatibility issue?

    Reply
    • Taiseer Joudeh says

      March 5, 2015 at 10:16 pm

      Nop, it is backward compatible and it contains bug fixes, check the release notes here.

      Reply
  16. Greg says

    March 5, 2015 at 1:29 pm

    In real world scenarios, is it wrong to let the resource and authorization server live in the same API? What are the pros(if any) and cons of this practice. Thank you

    Reply
    • Taiseer Joudeh says

      March 5, 2015 at 11:07 pm

      Hi Greg,
      It depends on your business case and if yor will build multiple resource APIs that relies on Authorization server, if this is case then it is better to separate them to avoid any code redundancy and you will have the Authorization in once place, if your API is simple and your business usecase will not require you building different resource APIs then you can keep both in the same project, but I recommend separate them from the beginning and use JWT for this.

      Reply
  17. Victor says

    March 6, 2015 at 12:01 pm

    Again great tutorial! Can’t wait for the next one, when will you publish it?

    BTW Any reason why you changed the naming convention from Repository (in your previous tutorials) to creating a Infrastructure folder with all the “repositories” in it? Readability perhaps?

    Reply
  18. kjsmith3 says

    March 15, 2015 at 6:40 pm

    After step 4 I when testing I get the error “Unsupported_grant_type”, Is there a way to fix this?

    Reply
    • Taiseer Joudeh says

      March 16, 2015 at 5:07 pm

      Elaborate more, this is showing when you are sending grant type not supported, the grant type used here is ‘Password’

      Reply
      • kjsmith3 says

        March 17, 2015 at 5:47 am

        sorry for the vague question.

        Using Postman I am sending the following request
        POST http://localhost:51624/oauth/token HTTP/1.1
        Host: localhost:51624
        Connection: keep-alive
        Content-Length: 0
        password: 0icu812
        Cache-Control: no-cache
        Origin: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
        grant_type: Password
        User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
        username: SuperPowerUser
        Content-Type: application/x-www-form-urlencoded
        Accept: */*
        Accept-Encoding: gzip, deflate
        Accept-Language: en-US,en;q=0.8
        Cookie: _ga=GA1.1.378465731.1404751833

        and getting the following response
        HTTP/1.1 400 Bad Request
        Cache-Control: no-cache
        Pragma: no-cache
        Content-Length: 34
        Content-Type: application/json;charset=UTF-8
        Expires: -1
        Server: Microsoft-IIS/8.0
        X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNca2VpdGhcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxM1xQcm9qZWN0c1xBc3BOZXRJZGVudGl0eVxBc3BOZXRJZGVudGl0eS5XZWJBcGlcb2F1dGhcdG9rZW4=?=
        X-Powered-By: ASP.NET
        Date: Tue, 17 Mar 2015 03:39:35 GMT

        {“error”:”unsupported_grant_type”}

        The code is identitical to what you have done in the tutorial, but I am not using LocalDB instead using SQLServer Express
        Because I have manually entered your example instead of performing a clone of your repository it is possible I have a type O.

        I am reusing your as:AudienceId and as:AudienceSecret keys instead of generating my own.
        If you can suggest where in the code a mistake might cause this type of issue it would be appreciated.

        Reply
        • kjsmith3 says

          March 20, 2015 at 8:15 am

          Can anyone tell me where to at least start debugging this. Based on what I’m seeing on the net it looks like I’m doing this right.

          I’ve tried but grant_type: Password and grant_type: password
          any help would be appreciated.

          Reply
        • Bob says

          April 9, 2015 at 10:11 am

          I got the same problem when testing it after step four, the error is:
          {
          “error”: “unsupported_grant_type”
          }

          Can you help? I followed everything in the tutorial. Thanks.

          Reply
          • Taiseer Joudeh says

            April 11, 2015 at 1:29 am

            Hi Bob, you still facing the errors? Make sure you are sending the request as the below, notice that Content-type header value:

            POST /oauth/token HTTP/1.1
            Host: localhost:59822
            Accept: application/json
            Content-Type: application/x-www-form-urlencoded
            Cache-Control: no-cache

            username=SuperPowerUser&password=MySuperP%40ss!&grant_type=password

          • Bob says

            April 12, 2015 at 1:20 am

            I checked the request details and did not see any problem (although my username and password are different asI added the user to the db), the problem could be the keys of “as:AudienceId” and “as:audienceSecret”? As I see from your blog, and the other one with one authorization server and resource server that are in different project, these two keys were generated there by adding an audience to the authorization server, correct?

            Thanks and really appreciate your help.

          • Bob says

            April 12, 2015 at 9:14 am

            Ok, finally, get it work! I added a new user using Postman, and tried it using Postman without any headers, then it works. See here:

            POST /oauth/token HTTP/1.1
            Host: localhost:1281
            Cache-Control: no-cache
            Content-Type: application/x-www-form-urlencoded

            username=bob&password=myP%40ss!&grant_type=password

            but you mentioned adding headers as above? Thanks and really appreciate you help.

  19. E. Timothy Uy says

    March 17, 2015 at 3:19 pm

    Another successful tutorial. Thank you Taiseer.

    Reply
    • Taiseer Joudeh says

      March 18, 2015 at 7:19 pm

      You welcome, glad you liked this series.

      Reply
  20. Alex Vance says

    March 18, 2015 at 9:00 pm

    Hi Taiseer, I love this post and happens to be directly related to what I’m needing right now. However, I have one problem. I’ve created a resource server separate from the Authorization server and i’ve noticed that if I don’t specify an Authorization header, it allows the request through (even with the authorize attribute). If i specify an authorization header with a bad value, it will properly deny the request. Any ideas?

    Reply
    • Taiseer Joudeh says

      March 19, 2015 at 9:54 am

      Hi Alex, that is strange, can you double check that you have those LOC in Startup correctly? Did you start Web API project from scratch or you used a template?

      Reply
      • Alex Vance says

        March 23, 2015 at 2:40 pm

        I’ve figured out what the problem was and it may be worth noting for others. I noticed on the response headers that the authorize header also had Negotiate and NTLM as authorization schemes. The IIS website instance I was installed under had them enabled, thus allowing authentication to occur. Once I turned them off, it worked as intended.

        Reply
  21. E. Timothy Uy says

    March 20, 2015 at 12:48 am

    If you are in a situation where you cannot trust the user and/or the network, is there a way to add more security between the client app and the server and still use Oauth2?

    Reply
    • E. Timothy Uy says

      March 20, 2015 at 12:54 am

      For example, would using mac-based tokens help? I guess that only secures the transaction after the user receives the access key and mac key.

      Reply
      • Taiseer Joudeh says

        March 20, 2015 at 6:00 pm

        You can’t use hmac authentication in clients that can’t store the secret confidentially, so this will not work with the AngularJS application I’m going to build.

        Reply
        • D. Mendez says

          July 3, 2015 at 5:01 pm

          But if you use bearer-tokens, you also have to store them confidentially. So what’s the difference. This is actually not a disatvantage of Mac-tokens in my opinion, because you have to store any authorization-information anyway. So why not using Mac-tokens, to prevent sending the secret (bearer-token) over the wire on every request?

          Reply
          • Taiseer Joudeh says

            July 4, 2015 at 2:56 am

            Storing secrets is different than storing bearer tokens. Bearer tokens expire and the access surface for it is limited, secrets or passwords is like a master key, if you put your hand on it you can control the entire account.

          • D. Mendez says

            July 6, 2015 at 9:58 am

            @Taiseer Joudeh
            Yeah. Okay i understand your point. But as much as i know you can also configure mac-tokens to expire. An refresh token exist for both of them. So if you have a refresh bearer-token you also have unlimited access. Furthermore can you also configure limit the surface to access with mac-tokens. Its just configuration. In my opinion the token-technique itselft doesn’t define the access-surface. Or am i wrong?

  22. JeremyWesley says

    March 24, 2015 at 7:48 pm

    Hi Taiseer,
    I’ve enjoyed reading your blog post around identity and web api security. If you wanted to secure a api method so that it could be accessed only by known client_id & client_secrets, how would you do this.

    An example would the create account method. We cant request that the user login to create and account but we want to restrict account creation to our known client_ids. Is there a correct way to do this or should the client_ID be passed in with the other new account information and handled inside the controller logic.

    I have looked and I cant seem to find a attribute that will check only ValidateClientAuthentication as Authorize seems to be about the whole set of credentials.

    Thanks for your feedback.

    Reply
    • Taiseer Joudeh says

      March 27, 2015 at 4:02 pm

      Hi Jermy,
      Sending the client_id and client_secret depends on the type of the client you are building (Confidential/Non-Confidential), so for non-confidential clients you cant store the client secret. Now you can use ValidateClientAuthentication method and send the client_id and client_secret in the request and validate them before generating a access token, if this failed then you do not generate a token the consumer will not be able to access the end point.
      Now in your case you need to special security to protect certain end point which only allows trusted clients to access it, well this reminds me of basic authentication where you send the username:password base64 encoded in the Authorization header with Basic scheme, and for this special end point you apply basic authentication authorize attribute, this post might be help.

      Reply
  23. Alex says

    March 26, 2015 at 4:42 pm

    Hi Taiseer, thanks for the tutorial! But I have one problem:
    when I check get method api/users (or post method api/changePassord) with Authorization header (Bearer eyJ0eXAiO….)
    I get an 401 Unauthorized status (“Authorization has been denied for this request.”)
    how to fix it?

    Reply
    • Taiseer Joudeh says

      March 26, 2015 at 4:47 pm

      Hi Alex,
      The api/ChangePassword endpoint should work if you have valid JWT (Not expired) but the api/users endpoint will work only when you obtain a token for user in “Admin” role, notice the [Authorize(Roles=”Admin”)] attribute.

      Reply
      • Alex says

        March 26, 2015 at 4:58 pm

        JWT I check in jwt.io – signature verified, not expired
        Attribute for endpoints ChangePassword and GetUsers – [Authorize]
        But I get 401 status (((

        Reply
        • Alex says

          March 26, 2015 at 5:20 pm

          Upload your code from GitHub – it works

          Reply
          • Alex says

            March 26, 2015 at 8:00 pm

            I found an error
            I had written:
            AccessTokenFormat = new CustomJwtFormat(“http://localhost:4878/”)
            must be:
            AccessTokenFormat = new CustomJwtFormat(“http://localhost:4878”)
            no character “/” at the end of string

  24. Alex says

    March 27, 2015 at 12:20 pm

    Hi Taiseer!
    There is one question:is it possible to find out the cause of invalid token (JWT)?
    incorrect issuer, expired date etc.

    Reply
  25. nbl says

    March 30, 2015 at 5:58 pm

    I have done everything as per the article above but I get this error: “error”: “unsupported_grant_type”. Any ideas on what this is caused by and how to get around it?

    Reply
    • sanddrr says

      April 7, 2015 at 12:34 pm

      Hi, I had the same error. Turned out I set username, password and grant_type as headers in the Advanced Rest Client instead of in the payload! 🙂

      Reply
  26. Jacob Cheriathundam says

    March 31, 2015 at 7:00 am

    Hi Taiseer, thank you so much for your articles, they have taught me so much!!

    I’m running into an issue that someone else mentioned in their comments. A return message of “Authorization has been denied for this request” when I attempt to do a change password call.

    I ran Postman requests for createuser, and oauth/token and both of those succeeded, the latter producing a jwt token similar to what I believe I should be expecting ({ “access_token”: “eyJ0eXAiOiJ…”, “token_type”: “bearer”, “expires_in”: 86399}). However when I run the “http://localhost:63344/api/accounts/changepassword” call, I get the authorization denied error.

    The one difference I made between my code and yours is that I set a public static string property on the CustomJwtFormat class that holds the “issuer” value. I did this so that I could be consistent everywhere with the Issuer value.

    My questions are,

    1) how exactly can I debug the underlying [Authorize] decorator? I’m sure that something is mismatched, but I have no idea where to look for that mismatch.

    2) If “Issuer” can be anything (a string or URI), then what is the purpose of it? Is best practice to use any particular way? Is one more secure than the other?

    Any help would be greatly appreciated! I need to figure this out before I can move on to your Claims tutorial.

    Thanks so much again for all your write ups, I’ve learned SO MUCH from them.

    Reply
    • Jacob Cheriathundam says

      March 31, 2015 at 7:15 am

      Please disregard, I figured out what was going wrong. In the process of debugging and guessing changes, I had changed the static issuer property that I created to be different than when it granted the token. The site http://jwt.io that Alex mentioned actually helped me resolve the issue.

      Thanks again! I’d still like to know if there is a best practice for the Issuer value and if there is a way to debug an authorize decorator, but now that I have it working, I can move on to the next article!

      Reply
  27. hpa says

    March 31, 2015 at 2:35 pm

    Great work. Very well documented.
    I have a question here. I am using Thinktecture identity server v2 to get ouath tokens (Resource owner flow).
    I am saving the access token received from thinktecuture server in a cookie on website.

    passing the same cookie when doing ajax request to web api 2.2. What UseJwtBearerAuthentication I have to set up in web api?

    Sorry for my silly question.

    Reply
  28. Mohamed Abdo says

    April 9, 2015 at 10:59 pm

    a reference & good article, but what about using Identity server http://identityserver.github.io/ , as alternative solution, what did you think about the level of maturity and extensibility, however in thinktecture, they are doing great stuff, but i found more sophisticated implementation, and even for the level of integration, and generally i don’t liked, but i have to stick to best available way to implement things, may i ask you for feedback and advice?

    Reply
    • Taiseer Joudeh says

      April 11, 2015 at 1:37 am

      Hi Mohamed,
      The Identity Server and what Dom and Brock built is amazing, it is full fledged and extensible Authorization server, but you need to understand what is doing so you can extend it and troubleshoot any issue facing when deploying/working on it.
      The only previous take about identity server is the documentation and the absence of simple steps to install it, but I guess this has changed recently and things are mature and organised, the guys spent decent time updating the documentation and GitHub wikis.
      So my recommendation is to use the identity server if you know what you are doing, but for someone want something quick and support minimal OAuth flows then he can depend on my post series.
      Hope this helps.

      Reply
      • Jeremy says

        May 18, 2015 at 6:02 am

        Except when it comes to ASP.NET 5. I don’t believe they are going to implement the Oauth server in ASP.NET 5 so it sounds like the Identity Server is the way to go going forward. Let me know if I’ve misunderstood.

        Reply
  29. Tshaiman says

    April 18, 2015 at 8:43 pm

    As always – Great post and much fun to read.
    few questions /remarks :

    1. Comparing this with the build-in template of WebAPI using VS2013 wizard there are minor changes, for example the VS template after setting the OAuthAuthorizationServerOptions options, calls the
    app.UseOAuthBearerTokens(OAuthOptions) where your code uses app.UseOAuthAuthorizationServer(OAuthServerOptions);
    what is the major diffrence between those two ?

    also VS 2013 ApplicationOAuthProvider (which is the CustomOAuthProvider in your code) is calling context.Request.Context.Authentication.SignIn(cookiesIdentity); as the final code on GrantResourceOwnerCredentials.

    Is that necessary ? I wonder why they did that , after all the API is stateless server, so why they are using this Autheticator.SignIn method ?

    2. What is the easiest way to generate as:AudienceId and as:AudienceSecret ? are there any rules regarding their length ?

    Thanks again.

    Reply
    • Tshaiman says

      April 19, 2015 at 11:18 pm

      disregard Question #2 it was already addressed in your JWT post. thanks !

      Reply
  30. Bob says

    May 7, 2015 at 9:04 pm

    Hello Taiseer, thanks for your great article on this topic.

    I have a ASP.NET MVC 5 application with default form authentication with cookies for regular web client(with browser), how can I add token based authentication for web api client? What changes need to be made, added and where (which file)?

    Thanks.

    Reply
  31. groovycoder says

    May 9, 2015 at 7:46 am

    Great series of blog posts! Very clear and everything worked.

    Reply
    • Taiseer Joudeh says

      May 12, 2015 at 12:13 am

      Glad to hear this, thanks for your message 🙂

      Reply
  32. Simba says

    May 9, 2015 at 8:45 am

    Hi Taiser

    Great article. I have worked my way successfully through part 1 and 2, I have run into problems at the “oauth/token” part, I am getting dreaded “IIS 8.0 Detailed Error – 404.0 – Not Found”, I have followed your tutorial to the letter. Is there something I missed?

    Reply
  33. nino2015 says

    May 12, 2015 at 12:39 am

    In your example you set the AccessTokenExpireTimeSpan to 24 hours. Does each successful request using a valid token reset the AccessTokenExpireTimeSpan back to 24 hours?

    Reply
    • Taiseer Joudeh says

      May 15, 2015 at 11:58 pm

      No this is not sliding expiration time, it is the time that access token will live for, it will end after 24 hours after you issue it.

      Reply
  34. Garima says

    June 29, 2015 at 11:30 am

    Very Nice Example 🙂
    I am beginner in this and have to start with DB first approach. Say I am already using aspnetDB in my aplication
    and I want to use it with that DB. How can I use this, any example you can provide.

    Reply
    • Taiseer Joudeh says

      June 30, 2015 at 12:25 am

      Hi Garima, you can google how you can add AspNet Identity with existing DB, lot of articles covering this topic.

      Reply
  35. Hemant Sathe says

    July 8, 2015 at 1:43 pm

    Excellent article. I have a question in context of Azure AD authentication. Your articles on that topic helped a lot. We are using Azure AD authentication in the project but not authorization. The application needs to add it’s own claims in the pipeline. These claims cannot be configured in Azure AD set up. The user management (adding removing users to application, creating access permissions based on security groups in AD etc.) is happening in Azure AD. However granting access to specific resources is defined in the application (essentially giving editing rights).
    I am not sure where to plug the code (adding new claims to identity). GrantResourceOwnerCredentials is not part of the pipeline since I don’t need authorization server. I also get bearer token which is already validated. Which is the correct point? Also how can I cache these claims so that I don’t have to go to the DB for each request.
    Thanks in advance.

    Reply
    • Taiseer Joudeh says

      July 9, 2015 at 1:14 am

      Hi Hemant, thanks for your message. This is interesting question that I have no answer for it now. I’m not sure if you can use your own claims with Azure AD as the token you received is issued by Azure AD tenant, so it contains all the claims already. Maybe you can ask Vittorio who always welling to help when it comes to Azure AD.
      As well check this repo which might help in your case.

      Reply
  36. den says

    July 9, 2015 at 11:58 am

    I have followed your example but get 401 on CORS preflight request (OPTIONS)

    Reply
  37. Christopher McCrum says

    July 9, 2015 at 8:58 pm

    Hey Taiseer, first I want to start with thank you so much for all your posts? It’s alot to digest but so far it’s all working (still trying to understand each part of it better tho haha). I do have a quick question for a scenario we have in our shop. We’re using a font-end ASP.NET Application and added all your security logic to the web api. Our workstations can be used by multiple users throughout the day as well

    1- We’d like to kick users out due to inactivity. Should we just use a session timeout and kick them back to the login screen? Once they log in again a new token would be issue right?

    2- Our management wants us to limit concurrent user access. So basically if I’m logged in to my computer, and then I log into another computer they would like the first computer not to have access anymore and be booted out. Do you have any thoughts on how that could be best achieved?

    Thanks again for all your support!

    Reply
    • Taiseer Joudeh says

      July 11, 2015 at 3:01 am

      Hi Chris, glad you found the posts useful.
      For both questions you need to store a reference on the database for each user/token issued, so if user x obtained token at certain time and he keeps sending this token to the back-end Api, you need to store in the database the last time of using this token, and with each request you validate the timespan between what stored in DB and what time of the request, if it was longer than the time out you specified then server issue 401 response.

      For the second question I guess you need to depend on the IP and store it inside the access token as claim, and with each request you need to make sure that the IP is not changed for the authenticated user.
      Hope this makes sense.

      Reply
  38. zhixing says

    July 13, 2015 at 5:15 am

    Dear Instructor,
    When I check your source code in github. I found in file “Web.config”:

    I am just wondering how you get the value = “414e1927a3884f68abc79f7283837fd1” for AudienceId and the value = “qMCdFDQuF23RV1Y-1Gq9L3cF3VmuFwVbam4fMTdAfpo” for AudienceSecret.

    Thank you!

    Reply
  39. Smith Samuel says

    July 14, 2015 at 2:01 am

    if you are having this error {“error”:”unsupported_grant_type”}, then it means your post is not well formed. Just follow this step in postman.
    1. The method should be POST.
    2. Enter the URL eg. http://localhost:9811/oauth/token
    3. Specify the following in the header
    Key value
    3.1 Content-Type application/x-www-form-urlencoded
    3.1 Accept application/json
    3.1 Post oauth/token http/1.1
    3.1 Host localhost:your port(eg 9811)

    4. Then go the body section. Select the raw option and type the following
    username=smithsamuel&password=xxxxxxxxxxxxx(use your password)&grant_type=password

    Then click on send.

    Reply
  40. nato24 says

    July 19, 2015 at 12:18 am

    Thanks for all your work in explaining this confusing space (as I can see from the amount of comments). Seems like there are a lot of way for inexperienced (and experienced alike) to miss something in this unforgiving space.

    It might be worth mentioning that there are currently no plans to port OAuthAuthorizationServerMiddleware to asp vnext.

    http://stackoverflow.com/questions/29055477/oauth-authorization-service-in-asp-net-mvc-6

    Reply
    • Taiseer Joudeh says

      July 21, 2015 at 10:20 am

      Thanks for your message, I guess they will integrate the ThinkTecture Identity server in ASP.NET 5 (https://github.com/aspnet/Security/issues/83)

      Reply
  41. Andrew Merisanu says

    July 19, 2015 at 4:23 pm

    Thank you for this excellent series, I learned so much about security.
    I am trying to combine the separation of Authorization and Resource servers with the refresh tokens and got a bit confused.
    in the ValidateClientAuthentication method the client validation is used in two different ways in the cases above. WHat is the way to combine validating the audience (for separation) and the client (for refresh tokens)? Can I use a different key for audience? like ‘audience_id ?

    TIA

    Andrew

    Reply
  42. Nicola says

    July 25, 2015 at 4:13 pm

    Hi Taiseer,
    I don’t know why, I have always this return message:
    “message”: “Authorization has been denied for this request.”
    I have downloaded your code to test.
    With postman I’m able to have a JWT Token calling “http://localhost:59822/oauth/token…”
    But, when I put the code in Bearer style (Bearer xxxxxx) to change password or get user lists I receive always the above message.
    Please help me.
    thanks in advance
    Nicola

    Reply
    • Taiseer Joudeh says

      July 27, 2015 at 4:25 am

      Hi Nicola,
      Make sure that all values in Step 6 for (Audience Id, Secret and Issuer) are the exact values (case sensitive) used in Step 4, I suspect that issuer value is different, please double check this.

      Reply
  43. stntz says

    July 30, 2015 at 1:33 pm

    Hi Taiseer,
    Thanks for your posts and guidelines.
    Quite helpful all the time and I have tried to read it all..

    The question I have regarding this post is how does User.Identity gets read if we are using a JWT?

    For example in the ChangePassword Method, you used User.Identity.GetUserID().

    Thanks.

    Reply
    • Taiseer Joudeh says

      August 8, 2015 at 7:01 am

      Hi,
      If you noticed, this method is attributed by [Authorize] attribute, so only authenticated users with valid JWT tokens can access it, so there should be established identity and the the extension method GetUserId will return the authenticated UserId, check how we set it here.

      Reply
  44. pchan says

    August 6, 2015 at 11:26 am

    Hi,

    Great write up, I am really enjoying reading these posts on authentications, and learning a lot from it.

    I am confused on audienceId, and audienceSecret, how did you generate those keys?

    Regards

    Reply
    • Taiseer Joudeh says

      August 8, 2015 at 7:32 am

      Hi, glad you find post useful.
      Please check step 1.4 from this post and look at the code in method: AddAudience. I have generated the Audience Id and Secret for this post up front ans daved them in Web.config as I have only one Audience.

      Reply
  45. JOY says

    August 11, 2015 at 12:57 pm

    hi Taiseer,
    I am a great fan of your blog.. I am (literally) following your code in my project.. but I am stuck at the consumption of my jwt token..at resurce api end
    My hosting environment is like this,
    domain.xxx/authServer
    domain.xxx/ResrcServer
    domain.xxx/webApps
    IN WHICH EACH PROJECT/ APPLICATION AS VIRTUAL DIRECTORY

    The thing is that token is successfully generated and all the information are there (after looking through http://jwt.io/) with some additional information like

    “http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider”: “ASP.NET Identity”,
    “AspNet.Identity.SecurityStamp”: “cc0177c1-349c-4bc9-842b-13561db52ba1”

    BUT WHENEVER I TRIED TO ACCESS SOME API’S FROM MY RESOURCE SERVER (WHICH IS DECORATED WITH [AUTHORIZE ] DIRECTIVE I ALWAYS GET 401 ERROR .. ( I EVEN ENABLE CORS BUT WITH NOT SUCCESS AND EVEN TRIED THE API FROM CHROME POSTMAN… ).. SO PLZ GIVE SOME INPUTS OR HOW TO DEBUG THIS ERROR AND WHERE CAN THERE BE ERROR IN MY CODE AS … AGAIN PLZ AS THE PROJECT IS TIME BOUND…

    my token consumption part is like this,

    private void ConfigureOAuthTokenConsumption(IAppBuilder app)
    {

    var issuer = “http://domainxxx/authServer”;
    string audienceId = ConfigurationManager.AppSettings[“as:AudienceId”];
    byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings[“as:AudienceSecret”]);

    // Api controllers with an [Authorize] attribute will be validated with JWT

    app.UseJwtBearerAuthentication(
    new JwtBearerAuthenticationOptions
    {
    AuthenticationMode = AuthenticationMode.Active,
    AllowedAudiences = new[] { audienceId },
    IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
    {
    new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
    }
    });

    }

    THANKS IN ADVANCE

    Reply
    • Taiseer Joudeh says

      August 15, 2015 at 1:22 am

      Hi Joy,
      Glad to know that my code is useful for your case, well the only thing I suspect that the issuer, audienceId, or audience secret value in your resource api is different from your Auth server, make sure that issuer value is using the same protocol (http) with no trailing slash at the end.

      Reply
  46. Milen says

    August 13, 2015 at 8:41 am

    To have a proper oauth 3-legged authentication every client needs to have registered a callback url. The server receives the client is and on validate clieny should redirect to this url with a temporary acess token. Then the client needs to call the server with this temporary token and then the servet must grant the permanent acess token Because all articles on asp.net web api seem to be neglectong this, would you be able to expand on your excellent article with this added step in oauth?

    Thanks

    Reply
    • Taiseer Joudeh says

      August 15, 2015 at 1:12 am

      Hi Milen, this is exactly the Authorization code grant, hopefully I will be able to extend this soon. Thanks for your comment

      Reply
  47. Ali Morlo says

    August 16, 2015 at 5:12 am

    Hi, big up for your post. how can i extend CustomJwtFormat class constructor to allow multiple issuer.
    Web with angular = “http://localhost:59822”
    Android = ???

    Sorry for the dummy question just a student trying to lurn

    Reply
  48. Christopher McCrum says

    August 18, 2015 at 1:57 am

    Hey Taiseer, your answers to my question helped..thanks again! Quick question, when I use jwt.io to decrypt my token I see that my user guid is in there as “nameid”: “c1e52007-777c-428a-a1eb-ce3a94d8d676”. I’m trying to figure out how to extract that in my controller after a user has been authorized.

    ClaimsIdentity userIdentity = (ClaimsIdentity)User.Identity;

    I noticed in ClaimsIdentity as I drill down deep into the results that the GUID is there but I’m not sure how to extract it properly without doing a bunch of string manipulation.

    [0] {http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier: c1e52007-777c-428a-a1eb-ce3a94d8d676} System.Security.Claims.Claim

    Reply
    • Christopher McCrum says

      August 18, 2015 at 10:42 pm

      For now I add a claim with the guid as the value but I don’t think this should be necessary being that it’s in the token already

      Reply
    • Taiseer Joudeh says

      August 18, 2015 at 11:07 pm

      Hi Chris,
      To get any claim from an established identity you can do as the code below:
      var identity = User.Identity as ClaimsIdentity;
      var userId = identity.Claims.First(i => i.Type == “YourClaimTypeHere”).Value;

      Hope this answers your question.

      Reply
      • Christopher McCrum says

        August 18, 2015 at 11:32 pm

        Thats what I’m doing now – but I’m not sure if it’s necessary to add the guid for the user as a claim being that it’s already in the token. Here’s my token decrypted from my dev environment.. I’m trying to extract nameid

        {
        “nameid”: “c1e52007-777c-428a-a1eb-ce3a94d8d676”,
        “unique_name”: “cmccrum”,
        “http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider”: “ASP.NET Identity”,
        “AspNet.Identity.SecurityStamp”: “a6d53dda-6c98-4b2c-b300-90484b2250b2”,
        “role”: [
        “Guru”,
        “User”,
        “Admin”
        ],
        “VendorId”: “1”,
        “iss”: “http://localhost/DeadBoltWebService”,
        “aud”: “83d372ae2f844c4d93afa3bc8d3a1901”,
        “exp”: 1439927694,
        “nbf”: 1439841294
        }

        I tried var nameClaim = identity.Claims.Single(x => x.Type == “http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier”); and that doesn’t work along with simply using nameid.

        Reply
  49. Valter says

    August 20, 2015 at 6:54 pm

    Hey Taiseer,

    How to request a token to use in a service/server?

    I try to use grant_type=client_credentials&client_id=CLICKID&client_secret=CLIENTSECRET&resource=WHATEVER
    and i keep getting “error”: “unauthorized_client”

    Any ideas? Do i have to config something in the OAuthAuthorizationServerOptions?

    Thanks,
    Valter

    Reply
    • Valter says

      August 20, 2015 at 11:52 pm

      Hey Taiseer,

      I figure out my issue… i didn’t override the GrantClientCredentials method.

      Thanks,
      Valter

      Reply
    • Taiseer Joudeh says

      August 24, 2015 at 11:32 pm

      Please check the grant “Client Credentials Grant” in this post, this should help you implementing client credential flow.

      Reply
  50. Jacob Cheriathundam says

    August 22, 2015 at 8:27 am

    Thank you so much for the tutorial Taiseer! You explain an incredibly difficult topic in very easy terms.

    I did run into one problem after tying all this in to a sample Angular App that I was building. Every so often, I’ll get this error “IDX 10223: Lifetime Validation Failed” that is tied to the JWT token (I’m assuming). My guess is that it’s an expired token on the server but somehow I need to catch this error in my client code. I wanted to track down where in my code it’s actually happening but my browsers start acting weird after I get the error. Chrome crashes if I open dev tools after getting this error (oddly enough, if I don’t open dev tools, the entire app works just fine). Visual Studio will throw an error from the code saying that the IDX error was encountered, but IE won’t let me navigate back to the code. Firefox Dev Edition throws, what seems to be, future errors that would occur if the token expired but doesn’t show me where the actual code is erroring out.

    Do you have any thoughts on how to handle this error? Should I be catching it in my authentication code? Should I put an httpinterceptor in place in Angular that monitors for this error (I’m assumign its a 401 error ultimately)?

    Any help would be greatly appreciated!

    Reply
    • Taiseer Joudeh says

      August 24, 2015 at 11:00 pm

      Hi Jacob,
      That is really interesting issue, well if I were in your case, then I will try using http interceptor where I will be monitoring 401 response. But in any case if the JWT is expired the server should never throw an exception, it should return 401 only. To make sure of this, please try to use expired JWT in a request to protected resource using PostMan and check the response, it should only return 401.
      Please share with me your solution, hope it will be an easy one.

      Reply
  51. alexismeillandAlexis says

    August 23, 2015 at 8:08 pm

    Hi,

    I have followed your tutorial. It’s awesome. But I have an issue.

    When I try to Change the password. I pass the bearer token.

    And I have a notimplemented exception on JwtFormat class in provider folder.

    public AuthenticationTicket Unprotect(string protectedText)

    Why is it going in this method?

    How can I fix it?

    Thanks,

    Reply
    • Taiseer Joudeh says

      August 24, 2015 at 10:53 pm

      Hi Alex,
      I’m not sure if you implemented something incorrectly in this class, but are you receiving this exception for all protected endpoints or just this one?

      Reply
      • alex says

        August 25, 2015 at 12:06 am

        Hi,

        Thanks I could fix it. The nugget Microsoft.Owin.Security.Jwt -Version 3.0.0 was not installed.

        Thanks!

        Reply
  52. alexismeilland says

    August 29, 2015 at 3:06 am

    Hi,

    I can create my token with postman and it works perfectly but with my app it does not work.I have the error:

    XMLHttpRequest cannot load http://localhost:7241/oauth/token. 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 400.

    I have enabled cors in my web api.

    And in my angularjs app.js file:

    $httpProvider.defaults.useXDomain = true;
    delete $httpProvider.defaults.headers.common[‘X-Requested-With’];
    // $httpProvider.defaults.withCredentials = true;
    $httpProvider.interceptors.push(‘AuthInterceptor’);

    I cannot sort it out. Any ideas?

    I tried with chrome anf irefox.

    Thanks,

    Reply
    • Taiseer Joudeh says

      September 7, 2015 at 6:52 am

      Hi,
      you need to allow it here too As well make sure you are using the same NuGet versions I’m using.

      Reply
  53. Avi says

    September 8, 2015 at 2:50 am

    Hi Taiseer, This absolutely awesome. I do have a question, let’s say a third party untrusted client is trying to accessing the web api. So obviously, I don’t want the user to create their account and authenticate via the third party client, how can I make sure third party request redirects to my webapi backend, so that they can authenticate on my webapi and then go back to the third party client once done.

    Reply
    • Taiseer Joudeh says

      September 10, 2015 at 1:05 pm

      Hi Avi,
      You need to use a different grant here which is the implicit flow or authorization code flow, where the user will enter his credentials not in the untrusted client, but directly in the authorization server. I didn’t implement this but this post will help you to achieve what you are looking for, or you can consider using the ThinkTecture Identity Server.

      Reply
      • Avi says

        September 10, 2015 at 9:23 pm

        Thanks Taiseer. I’m thinking of looking at the Thinktecture Id server.

        Reply
  54. Jeroen-bart Engelen says

    September 10, 2015 at 6:29 pm

    Great article, but I’m having trouble getting it to work.
    I’ve made a test project based on this article and this (http://odetocode.com/blogs/scott/archive/2015/01/15/using-json-web-tokens-with-katana-and-webapi.aspx) article. The project succesfully creates a JWT token, but I cannot perform any requests using that token. I keep getting an HTTP 401 error. The problem is that I have no idea how to debug this inner process. It;s all handled by the Authorize attribute. Do you have any pointers how to troubleshoot this problem?

    Thanks!

    Reply
    • Taiseer Joudeh says

      September 10, 2015 at 6:46 pm

      Hi Jeroen, this issued JWT token should be trusted by your resource APi, please check step 6 from my post and make sure that AudienceId, secret and issuer are all set correctly.

      Reply
      • Jeroen-bart Engelen says

        September 10, 2015 at 9:04 pm

        After building the complete Owin framework from source to be able to debug it, I was able to solve it.
        I’m using Web API and I want my API calls to be authorized. A call with bearer token was denied constantly, even though I was able to get an OAuth token.
        I put a breakpoint on AuthenticateCoreAsync() in OAuthBearerAuthenticationHandler from the Microsoft Owin security library I noticed it wouldn’t get hit. At all. As if the authentication middleware wasn’t loaded. I checked my implementation 10 times and it all seemed good. Per chance I requested the index page (which is just an empty directory) and then the breakpoint was hit! But for some reason, requesting the Web API endpoint didn’t work.
        I then changed the order in which I loaded the middleware from:
        app.UseWebApi(config);
        app.UseJwtBearerAuthentication(new JwtOptions());
        app.UseOAuthAuthorizationServer(new OAuthOptions());

        to:
        app.UseJwtBearerAuthentication(new JwtOptions());
        app.UseOAuthAuthorizationServer(new OAuthOptions());
        app.UseWebApi(config);

        and then it worked….
        I would’ve never thought the order would be important….

        Reply
        • Achilleas says

          March 7, 2016 at 5:37 pm

          The order is indeed important! I was getting 401 too, and then changed the order from:
          HttpConfiguration httpConfig = new HttpConfiguration();

          ConfigureOAuthTokenGeneration(app);

          ConfigureWebApi(httpConfig);

          app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

          app.UseWebApi(httpConfig);

          ConfigureOAuthTokenConsumption(app);

          To:
          HttpConfiguration httpConfig = new HttpConfiguration();

          ConfigureOAuthTokenConsumption(app);

          ConfigureOAuthTokenGeneration(app);

          ConfigureWebApi(httpConfig);

          app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

          app.UseWebApi(httpConfig);

          and it worked!

          Thank you so much for finding that out, you really saved hours of work for such a silly problem!

          Reply
  55. Carlos Boichuk says

    September 13, 2015 at 11:27 pm

    Taiseer, this is an excellent article, I have a question about how to customize the json web token consumption in a web api resource server, i want to not only validate the json web token receive on each request also i want to read the token received, which methods should i override in the web api resource server in order to perform the current json web token validation as the one you mentioned in this article and in the others, and implementing this kind of additional logic to it ?

    Thanks for your articles, ill be waiting for your reply.

    Reply
    • Taiseer Joudeh says

      September 18, 2015 at 2:50 pm

      Hi Carols, I need to check this, if you find an answer please share it.

      Reply
  56. Michael Heribert says

    September 20, 2015 at 11:08 am

    Hi, thank you for the great tutorial, it helped me a lot! Could you pls explain how exactly you implemented the as:AudienceId and Secret? How can I create the values for my application? And when using the function linked in the description, how should it be implemented into the application?

    thanks in advance 🙂

    Reply
    • Michael Heribert says

      September 20, 2015 at 8:59 pm

      Hi, I managed to solve the problem: using the x-www-form-urlencoded option for the body produces an error, using the raw tab instead solved the problem whereas I expected the audience-key to be the source of the problem.
      greetings
      Michael Heribert

      Reply
      • Taiseer Joudeh says

        October 3, 2015 at 5:51 pm

        You are welcome Michael, thanks for you comment and happy to hear you solved the issue.

        Reply
    • Manuel Espino says

      December 15, 2015 at 7:08 pm

      Hi Michael

      I’m trying to create my own audience id and secret, could you please tell me how you managed to create your own?

      Thanks in advace!

      Reply
    • Russell Wyatt says

      March 5, 2016 at 11:25 am

      I would like an answer to this too. It’s a great tutorial but this bit has left me a bit high and dry. Am I to build this class into another application to generate the values? Can you expand on this please?

      TIA

      Reply
  57. mbeddedsoft says

    September 21, 2015 at 12:17 am

    Getting error testing out access token. The error is unsupported_grant_type.

    Request: http://localhost:59822/oauth/token

    Status

    400 Bad Request Show explanation Loading time: 93
    Request headers
    username: SuperPowerUser
    Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo
    X-DevTools-Emulate-Network-Conditions-Client-Id: 186AD051-64D8-4890-9BBE-47F7B6309430
    grant_type: password
    User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36
    password: MySuperP@ssword!
    Content-Type: application/x-www-form-urlencoded
    Accept: */*
    Accept-Encoding: gzip, deflate
    Accept-Language: en-US,en;q=0.8
    Cookie: __RequestVerificationToken_L2JvcmRlcnRpeA2=qA73L3FxlS562JBDGKjR-ch6bnrrlW-zFqx5ntdDAZPZpI7C9nOAoj4uRvDKPNYXepRSZJHOwixnlmp9forV22k0kn-atcTIfhi8AnJ4fwk1; __RequestVerificationToken=AqounhGRCOyT_drnSmV_aIsJQ8Nl0eRJkwECTarf079Iuqmi9AQVaeEXUMQ_0WH6B8KQW_j7lq-H5FxPBUPWZqRPaEXTNNfslOmdTDfzG4U1

    Response headers
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 34
    Content-Type: application/json;charset=UTF-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcbWFya1xkb2N1bWVudHNcdmlzdWFsIHN0dWRpbyAyMDEzXFByb2plY3RzXFdlYkFwcDFcV2ViQXBwMVxvYXV0aFx0b2tlbg==?=
    X-Powered-By: ASP.NET
    Date: Sun, 20 Sep 2015 21:08:55 GMT
    Raw
    JSON

    {“error”:”unsupported_grant_type”}

    I did some research and most of the stuff I found said to add the existing line in GrantResourceOwnerCredentials()…

    context.OwinContext.Response.Headers.Add(“Access-Control-Allow-Origin”, new[] { “*” });

    Since this is already in CustomOAuthProvider.GrantResourceOwnerCredentials(), I’m kinda stuck.

    Do you have any ideas?

    thanks,

    Reply
    • pepek says

      November 20, 2015 at 5:48 pm

      Hi. I guess username, passwod and grant_type should be sent in body not in headers

      Reply
      • Taiseer Joudeh says

        November 24, 2015 at 1:34 pm

        Hi Pepek, Nothing sent in the headers, it is sent in the body as UrlEncoded content type.

        Reply
    • Hrvoje says

      May 4, 2016 at 11:55 pm

      It is totally misleading message.
      The real problem is that Password hash in User table wasn’t correct.

      Put the following code in GrantResourceOwnerCredentials function of CustomOAuthProvider class:

      var pHasher = new Microsoft.AspNet.Identity.PasswordHasher();
      string hashed = pHasher.HashPassword(“HPSWD001”);

      /* PUT BREAKPOINT TO FOLLOWING LINE and use watcher in debugger to inspect hashed variable
      Compare hashed variable with the data stored in PasswordHash column in User table. It should be the same.
      After I changed that, everything started to work. */

      ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

      Reply
      • cicciuzzo says

        June 15, 2016 at 1:35 pm

        Hi

        I have the same problem..

        I try to add the code that suggest @Hrvoje but dosen’t work because the Hash password is differnt than ordifina password..

        I try also to hard coded the usen name and password in line 35 in CustoOAuthProviders.cs

        ApplicationUser user = await userManager.FindAsync(“SuperPowerUser”, “MySuperP@ss!”);

        and hashed password

        ApplicationUser user = await userManager.FindAsync(“SuperPowerUser”, “ANQ/JYqtnfCMmOHUMj9MZdXOhOpnqwVVJiik8A36jAr9jDyftg6OTtr5a0Q17toUlw==”);

        But this method don’t found the user in the database and I don’t undestand…

        I download the your source to compare the code and ara same

        can you help me, please?

        Reply
  58. mbeddedsoft says

    September 21, 2015 at 5:09 pm

    I had a problem when I accidently updated packages to latest versions for *.owin.* in PM. I meant to only update EF and the .net framework to 4.5.1. After updating I noticed that the method ‘public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)’ was not being called. I set a breakpoint in the method and it never hit when I tried making a REST client to call POST http://localhost:port/oauth/token with username, password, and grant_type params. Reverting back to the 2.0 versions identified in article 1 fixed this.

    Would you know why this would be? Just asking.

    BTW, I am really enjoying your article. Good information. I also really appreciate all the referenced links and articles. You are doing a fantastic job. It’s good to be able to follow the tutorial and also have references to more detailed information on Identity 2.0 and OWIN.

    thank you so much.

    Reply
    • Prashanth says

      October 11, 2015 at 7:41 am

      Hi mbeddedsoft,
      Even I am facing same problem. Could u plz explain what have u done to solve this. Plz give more info about which package needs to update ?

      Reply
  59. V says

    September 22, 2015 at 5:00 pm

    Great post. By registering client id with Authorization server, and securing the JWT token by signing and encryption, are we acheiving the OpenIDConnect 2.0 specifications. Can you please clarify.

    Reply
  60. Daniel says

    September 30, 2015 at 5:38 pm

    Hi Taiseer,

    Many thanks for your article. It is very interesting and helpful for someone like me who’s not a server expert 🙂

    I learnt a lot from your article and I’ve done all the steps. But I’ve got an issue that you don’t seem to have, and I don’t know why.

    1. I can generate IDs and Secrets, no problem, and also request the token. But the response (containing the token) is not properly formatted. PostMan says there’s no headers, and the characters are unknown. Do you have an idea ?

    2. Bonus question : Which function is hit when I call the URL for retrieving the token (localhost:xxxxx/oauth/token) ? I would like to do some debugging for 1., but my breakpoints don’t stop the flow.

    Thanks a lot !

    Reply
    • Taiseer Joudeh says

      October 3, 2015 at 6:11 pm

      Hi Daniel,
      For your second question you can put breakpoints in methods “ValidateClientAuthentication” and “GrantResourceOwnerCredentials” in the class which inherits from “OAuthAuthorizationServerProvider”.
      For your first one I didn’t really understand it, can you elaborate more please?
      Regards,
      Taiseer

      Reply
  61. iliya says

    October 8, 2015 at 7:31 pm

    Hi Taiseer!
    thanks very much, it’s best solution for authentication and authorization in web api.
    i have some important questions :
    1.in step 3 inside “CustomJwtFormat” and step 6 inside “ConfigureOAuthTokenConsumption”, you used static value from app setting for sample, is it true? but in real Project we can’t do that because audience id and audience secret are different for each user… so what should we do?

    2.in step 6 inside “ConfigureOAuthTokenConsumption” how can i read JWT tokens that sent clients with their requests?
    instead this code :
    string audienceId = ConfigurationManager.AppSettings[“as:AudienceId”];
    byte[] audienceSecret = TextEncodings.Base64Url.Decode(ConfigurationManager.AppSettings[“as:AudienceSecret”]);

    and how should i check user’s token with the user?

    Reply
  62. Mike Olson says

    October 9, 2015 at 10:16 pm

    I have implemented this tutorial, but when I secure my WebAPI methods with the AuthorizeAttribute they become unavailable, and nothing actually consumes the Jwt Token. There are no errors or anything, so I’m not sure what I’m missing. I can see that the token is created, it is passed back to Angular, and it is included in subsequent requests from Angular to the WebAPI. I can even write a custom AuthorizeAttribute, and if I break in there I can see that the token is in the header of the request. I’m going crazy trying to figure this out. Can you help me?

    Reply
    • Taiseer Joudeh says

      October 12, 2015 at 10:19 am

      Hi Mike,
      What do you mean by the become unavailable? You mean Unauthorized?
      You need to make sure that issuer and audience id are exactly the same in Resource API, use JWT.IO to check your JWT token and inspect the claims inside it.
      Hope this will help.

      Reply
      • Mike Olson says

        October 12, 2015 at 5:40 pm

        Sorry I should have been more clear…

        The JWT token is present in the request, but no ClaimsIdentity is created (that I can so), and just overall I can’t find any information about the user context based on what was in the JWT token. The one thing I did differently from your tutorial was to skip all the stuff with the UserManager, since I have a previously existing user database that I’m hooking into, so I wonder if that’s part of the problem, but it didn’t seem like it should be.

        I did wonder if it was because the issuer and audience IDs weren’t the same, but they are. I checked using JWT.IO and I even made them string constants in the code, and the code that issues uses the same constants as the code that calls UseJwtBearerAuthentication.

        Reply
        • Mike Olson says

          October 13, 2015 at 10:58 pm

          I figured out what I was doing wrong. I put app.UseWebApi(config) at the top of the Startup code instead of the bottom. So it was sending me to WebAPI before the authorization modules were ever getting called. I asked the question a little better over at the ASP.NET forums and got an answer:
          http://forums.asp.net/p/2070482/5976299.aspx?p=True&t=635803483826595456

          Reply
  63. Senthil says

    October 23, 2015 at 7:26 pm

    Thank you so much for the wonderful article.

    I created two separate API projects for AS & RS.

    Token created from AS is perfectly working as excepted in RS.

    But when I use the same token in AS, it goes to Unprotect(string protectedText)

    I saw the first comment with same case, but I updated Microsoft.Owin.Security.Jwt 3.0.1.0

    AS having other Controllers without Authorize and I am able to get result from those.

    If I use Authorize Bearer in AS – it goes to Unprotect method.

    Here is my CustomJwtFormat class:

    public class CustomJwtFormat : ISecureDataFormat
    {
    private readonly string _issuer = string.Empty;
    private const string AudiencePropertyKey = “audience”;

    public CustomJwtFormat(string issuer)
    {
    _issuer = issuer;
    }

    public string Protect(AuthenticationTicket data)
    {
    if (data == null)
    {
    throw new ArgumentNullException(“data”);
    }

    string audienceId = data.Properties.Dictionary.ContainsKey(AudiencePropertyKey) ? data.Properties.Dictionary[AudiencePropertyKey] : null;

    if (string.IsNullOrWhiteSpace(audienceId)) throw new InvalidOperationException(“AuthenticationTicket.Properties does not include audience”);

    Audience audience = AudienceManager.FindAudience(audienceId);

    string symmetricKeyAsBase64 = audience.Base64Secret;

    //var keyByteArray = TextEncodings.Base64Url.Decode(symmetricKeyAsBase64);
    var keyByteArray = Convert.FromBase64String(symmetricKeyAsBase64);

    var signingKey = new HmacSigningCredentials(keyByteArray);

    var issued = data.Properties.IssuedUtc;

    var expires = data.Properties.ExpiresUtc;

    var token = new JwtSecurityToken(_issuer, audienceId, data.Identity.Claims, issued.Value.UtcDateTime, expires.Value.UtcDateTime, signingKey);

    var handler = new JwtSecurityTokenHandler();

    var jwt = handler.WriteToken(token);

    return jwt;
    }

    public AuthenticationTicket Unprotect(string protectedText)
    {
    throw new NotImplementedException();
    }

    Here is my Startup class:

    public void Configuration(IAppBuilder app)
    {
    HttpConfiguration config = new HttpConfiguration();

    ConfigureOAuthTokenConsumption(app);
    ConfigureOAuthTokenGeneration(app);

    //I tried changing the above order

    //WebApiConfig.Register(httpConfig);

    ConfigureWebApi(config);

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

    UnityConfig.RegisterComponents(config);

    TeamManagement.WebApi.App_Start.AutoMapperConfig.RegisterMaps();
    }

    Can you please help where am doing mistake?

    Reply
    • Senthil says

      October 23, 2015 at 7:57 pm

      Finally found!!!

      private void ConfigureOAuthTokenGeneration(IAppBuilder app)
      {

      app.CreatePerOwinContext(ApplicationDbContext.Create);
      app.CreatePerOwinContext(ApplicationUserManager.Create);

      OAuthAuthorizationServerOptions oAuthServerOptions = new OAuthAuthorizationServerOptions()
      {
      AllowInsecureHttp = true,
      TokenEndpointPath = new Microsoft.Owin.PathString(“/oauth/token”),
      AccessTokenExpireTimeSpan = TimeSpan.FromDays(6),
      Provider = new CustomOAuthProvider(),
      AccessTokenFormat = new CustomJwtFormat(“http://localhost:50658”)
      };

      //app.UseOAuthBearerTokens(oAuthServerOptions);
      app.UseOAuthAuthorizationServer(oAuthServerOptions);
      }

      The commented line was the problem. Sorry, it was my fault but that made me to learn more!!!

      Thanks a bunch 🙂

      Reply
      • Taiseer Joudeh says

        October 26, 2015 at 10:41 am

        You are welcome, glad you find the issue.

        Reply
  64. Senthil says

    October 23, 2015 at 8:14 pm

    We register allowed Audiences on Startup in both AS & RS.

    When client ids are stored in DB, how do RS & AS know about newly registered client ids? – Do we need to restart the app just to get latest added audiences? Is there any better way to do?

    I just think, but don’t know good or bad:

    Can we use ConcurrentList along with Audience DB, I mean when new Audience added, we should add in both Audience store and ConcurrentList and when IIS refresh then on Startup class, all exists Audiences in ConcurrentList again.

    Am not sure – it just an idea…

    Reply
  65. Denys Olleik says

    October 29, 2015 at 7:35 am

    Taiseer, what a great blog, bravo! It helped me a lot coming into world of web development. One suggestion…

    I recently stumbled upon trying to figure out if I want to implement refresh token and carry the burden of extra complexity. I needed a way to easily disable the account to prevent user from using their token from making further requests against the api.

    I have modified ConfigureOAuthTokenConsumption(). Setting JwtBearerAuthenticationOptions.Provider to a custom provider, you can override OAuthBearerAuthenticationProvider.ValidateIdentity. You can at this point use the user GUID form incomming token to load the actual identity from database and pass it to context.Validated(identity), this gives you ability to always load fresh credentials with every request.

    You can add a flag to check if user is active (requires extra column in database to keep track of active users) this way.

    Reply
    • Taiseer Joudeh says

      November 6, 2015 at 4:04 am

      Hi Denyes,
      The draw back of this approach is hitting the database with each request to validate user identity, well.. this somehow breaks the stateless nature of the bearer tokens, but if you are fine with this you can do it for sure.

      Reply
  66. Manuel Espino says

    November 6, 2015 at 6:45 pm

    Hi Taiseer

    First of all, thank you for this articles. They have helped me to understand OAuth Authentication.

    I followed the steps and I don’t see errors when I build the project also runs without exceptions, but when I test and I try to obtain the JWT Token, PostMan shows me an error:

    “Invalid object name ‘IdentityUserClaims’

    This is throwing when the following line is executed:

    User user = await userManager.FindAsync(context.UserName, context.Password);

    In my BD already have the table AspNetUserClaim but I’ve not be able to find out the root of the problem.

    Could you please advise me or point me to the right direction?

    Thanks in advance.

    Reply
    • Taiseer Joudeh says

      November 11, 2015 at 6:54 pm

      You are welcome Manuel.
      Did you try to create your own UserStore and RoleStore, or did you try to configure Asp.Net identity database tables?

      Reply
      • Manuel Espino says

        December 16, 2015 at 8:08 am

        Sorry for the late response, and yes, the problem was a misspelling in the table names (dang!)

        Reply
  67. Sophonias Dechasa says

    November 10, 2015 at 11:50 pm

    Hey Taiseer, I just wanted to thank you for your thorough tutorials after combining many of your tutorials I finally created my own middleware. Your tutorials are by far the best I’ve seen. Keep up the good work. Thanks.

    Reply
    • Taiseer Joudeh says

      November 11, 2015 at 6:44 pm

      Always happy to help, thanks for your comment 🙂

      Reply
  68. john says

    November 11, 2015 at 7:19 am

    Hi Taiseer, This has been a great tutorial, I have my own angular front end in development against it. Unfortunately tonight the /oauth/token path has started giving me a 404, I’ve rolled back several commits to see if I bonked something along the way and no luck.

    Is there a way I can verify that the /oauth/token route is being created/bound correctly? Do you have any other suggestions or things I can check? Thank you in advance.

    Reply
    • Taiseer Joudeh says

      November 11, 2015 at 6:44 pm

      Hi John,
      Giving 404 suddenly means there is change happened on your Angular UI project, I recommend you to use postman to test the back-end and then you can fire fiddler and monitor the requests sent to the Api and see if the URL is correct.

      Reply
      • Reza says

        November 12, 2015 at 7:00 am

        Hi Taiseer,

        Thanks for the article. It has helped me a lot on using oauth and JWT. The solution works flawlessly in IIS express, but deploying to IIS 8.5 I get 404 error on http:/localhost/oauth/token. Searching for answer, I’ve updated web.config with all the settings that I found in replies on Stackoverflow. could you please reflect how you host this solution in IIS?

        Thanks,
        Reza

        Reply
        • Taiseer Joudeh says

          November 16, 2015 at 7:29 pm

          Hi Reza, that is strange, currently I’m hosting on Azure Web Apps, I assume they are using latest IIS version.

          Reply
          • Reza says

            November 27, 2015 at 6:26 pm

            Hi Taiseer,

            Thanks for the reply. It was my silliness which I found I had ensured in release mode build, AllowInsecureHttp was set to false.

            Thanks,
            Reza

  69. Sam says

    November 16, 2015 at 8:11 am

    Hi Taiseer,
    Thank you for uploading above tutorial, Can you please tell me how can I add api version in token signature. I cant figure out this.Thank you very much again learned lot from this article.
    {
    access token:
    token Type:
    expires in:
    Version:
    }

    Regards,
    Sam.

    Reply
    • Taiseer Joudeh says

      November 16, 2015 at 7:20 pm

      Hi Sam, if you want to return something in the response of the token endpoint then you can check my SO answer here.

      Reply
      • Sam says

        November 17, 2015 at 7:51 am

        Yesterday I found the same but didnt notice it also from you. Thank you much sharing your knowledge.

        Reply
  70. Spike Pierson says

    November 17, 2015 at 8:05 pm

    Hi Taiseer,

    I am posting this in the blog for Part 3 because this is where I’m getting stuck. At the end of Step 4, you direct us to test the ability to start issuing JWT access tokens, by issuing an HTTP POST request to http://localhost:nnnnn/oauth/token with the x-www-form-urlencoded data shown in your diagram. I am using Fiddler as my proxy. The POST request looks like this:

    POST http://localhost:55383/oauth/token HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:55383
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 67

    grant_type=password&username=SuperPowerUser&password=MySuperP%40ss!

    I am consistently getting this response:

    HTTP/1.1 400 Bad Request
    Cache-Control: no-cache
    Pragma: no-cache
    Content-Length: 87
    Content-Type: application/json;charset=UTF-8
    Expires: -1
    Server: Microsoft-IIS/8.0
    Access-Control-Allow-Origin: *
    X-SourceFiles: =?UTF-8?B?QzpcVXNlcnNcc3BpZXJzb24uQUdFUlBPSU5UXERvY3VtZW50c1xXZWIgQVBJXEFzcE5ldElkZW50aXR5XEFzcE5ldElkZW50aXR5LldlYkFwaVxvYXV0aFx0b2tlbg==?=
    X-Powered-By: ASP.NET
    Date: Tue, 17 Nov 2015 16:28:34 GMT

    {“error”:”invalid_grant”,”error_description”:”The user name or password is incorrect.”}

    I found that the reason for this response is because in the CustomOAuthProvider class that was added in Step 1, in the GrantResourceOwnerCredentials method, the call to userManager.FindAsync always returns a null user object. Therefore, the call to context.SetError is always called, and the 400 response is always issued. I tried single-stepping into the userManager.FindAsync method, but to no avail. I know where it’s breaking, but have no idea as to why. Is there something that I’m overlooking here? Could you please advise me or point me in the right direction? I would greatly appreciate it. Thanks in advance.

    Reply
    • Taiseer Joudeh says

      November 24, 2015 at 1:45 pm

      Hi,
      It is basically not matching username/password from the database with what you are trying to send, you can hard-code username/password, test and you should get an access token. So your issue with validating username/password.
      Make sure that password is encoded/decoded correctly before sending it to the password manager.

      Reply
  71. Jonathan says

    November 18, 2015 at 10:23 am

    {
    “access_token”: “JWT_Token”,
    “token_type”: “bearer”,
    “expires_in”: 1799,
    “refresh_token”: “8369ac755bdc4e3fa9d3f5870b3af2a0”,
    “as:client_id”: “10b7c34b2c184d86aa716ecd7a82acb4”,
    “userName”: “testUser”,
    “.issued”: “Wed, 18 Nov 2015 06:23:04 GMT”,
    “.expires”: “Wed, 18 Nov 2015 06:53:04 GMT”
    }

    Can I replace with the following Json result:
    {
    “returnCode”: 200,
    “message”: “Custom Message”,
    “data”: {
    “access_token”: “JWT_Token”,
    “token_type”: “bearer”,
    “expires_in”: 1799,
    “refresh_token”: “8369ac755bdc4e3fa9d3f5870b3af2a0”,
    “as:client_id”: “10b7c34b2c184d86aa716ecd7a82acb4”,
    “userName”: “testUser”,
    “.issued”: “Wed, 18 Nov 2015 06:23:04 GMT”,
    “.expires”: “Wed, 18 Nov 2015 06:53:04 GMT”
    }
    }

    Reply
    • Taiseer Joudeh says

      November 24, 2015 at 1:38 pm

      If you want to change the response you can do this, its up to you

      Reply
      • Jonathan says

        November 30, 2015 at 7:18 am

        I mean there is no easy way to change response json format, unless intercept and modify OWIN Body Response Stream. Right?

        Reply
  72. Shaun says

    December 16, 2015 at 11:19 pm

    Thank you for this tutorial, I now have a working security model for my WEB API, I am creating.

    One question though: If IIS is reset, will all outstanding JWTs still work or will they need to be reissued?

    Reply
    • Taiseer Joudeh says

      December 23, 2015 at 6:32 pm

      Sure thing, all JWT issues will be working, those are self contained tokens and IIS has nothing to do with them

      Reply
  73. Ronald says

    December 21, 2015 at 1:57 pm

    Great series! They are really helpfull! But I’m kinda stuck at the moment.

    i can get the access_token from the token endpoint, no problem. but when I try to use the token to reach one of my controller actions with an {Authorize] attribute I get 401.

    My get request looks as follows:

    url: http://localhost:51388/api/crm/accounts
    Headers:

    Accept: application/json
    Content-Type: application/json
    Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1laWQiOiI3YjIyN2MyYi0wNmZhLTQ4NmEtYjIyZC0wMWJmODRlMjc4YjIiLCJ1bmlxdWVfbmFtZSI6IkFkbWluIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9hY2Nlc3Njb250cm9sc2VydmljZS8yMDEwLzA3L2NsYWltcy9pZGVudGl0eXByb3ZpZGVyIjoiQVNQLk5FVCBJZGVudGl0eSIsIkFzcE5ldC5JZGVudGl0eS5TZWN1cml0eVN0YW1wIjoiZTA5NDA4ZjktM2I3MS00NGI0LTkyNDMtNmM3MWMwY2E3ZGI0Iiwicm9sZSI6IkFkbWluaXN0cmF0b3IiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUxMzg4LyIsImF1ZCI6IjQxNGUxOTI3YTM4ODRmNjhhYmM3OWY3MjgzODM3ZmQxIiwiZXhwIjoxNDUwNzc5ODcwLCJuYmYiOjE0NTA2OTM0NzB9.mbcByoYt2STkwfrJsWJyJ35PUE2-4kis-UAy9RU-KBs

    and my controller looks like this:

    [HttpGet]
    [Route(“”)]
    [Authorize]
    public IHttpActionResult Accounts()
    {
    var accounts = _uow.Repository().GetAll(a => a.ParentAccountId == null, “Addresses”, “PhoneNumbers”, “EmailAddresses”);
    var accountDtos = Mapper.Map<IEnumerable, List>(accounts);
    return Ok(accountDtos);
    }

    I don’t really know where to start looking to find out why it keeps giving me te 401. I have compared the example code and my code a couple of times, but it looks good te me. Any ideas on where to look?

    Reply
    • Taiseer Joudeh says

      December 24, 2015 at 2:59 am

      Please check this comment which might help in debugging your issue

      Reply
  74. treetopvt says

    December 22, 2015 at 2:00 am

    I first want to thank Taiseer for this excellent set of tutorials. I’ve walked through this and the one on creating a Token server and I’ve found both to be well-written and a great primer into owin middleware and tokens. If you are having problems with 401s, you can read the story, or jump to my solution!

    The first time I walked through this set of blogs I was up and running and moved on to other tasks. I then tried to implement it from memory and was not able to validate endpoints with tokens (401). After going line by line through my code and nuget versions I did not find a difference from my working example.

    So, I created another one that was far simpler, removing everything not directly related to webapi2, owin, or tokens, starting from an empty web project. The result, still not able to authenticate tokens with the JwtBearerAuthentication middleware.

    This lead me down the rabbit hole of owin middlewares, how they function, are built, etc. Nothing I tried, and I everything the internet could suggest worked for me.

    I eventually learned how to build my TokenHandler, deriving from JWTSecurityTokenHandler. Overriding that gave me great insight into how OWIN processes and validates tokens.

    I discovered that the ValidateToken function was throwing exceptions, which leads to the token to be considered not valid. The obvious reasons for an invalid token:issuer, audience, keys not matching, were all triple-checked and confirmed to be the same on both ends. So why and where was an exception being raised?

    The culprit ended up being the ValidateAudience method. First, I was surprised this was a method and not a function, but I am sure there is a valid reason for this! I do not know why it was failing, but I ended up calling the base method from my overridden ValidateToken function with the code that follows. Result? Success! So two days of banging my head against the OWIN wall I am ready to move on again, with a much greater appreciation/frustration for MS’s implementation of middleware.

    public override ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
    var jwt = this.ValidateSignature(securityToken, validationParameters);
    if (validationParameters.ValidateAudience)
    {
    if (validationParameters.AudienceValidator != null)
    {
    if (!validationParameters.AudienceValidator(jwt.Audiences, jwt, validationParameters))
    {
    throw new SecurityTokenInvalidAudienceException(string.Format(CultureInfo.InvariantCulture, ErrorMessages.IDX10231, jwt.ToString()));
    }
    }
    else
    {
    base.ValidateAudience(validationParameters.ValidAudiences, jwt, validationParameters);
    }
    }

    string issuer = jwt.Issuer;
    if (validationParameters.ValidateIssuer)
    {
    if (validationParameters.IssuerValidator != null)
    {
    issuer = validationParameters.IssuerValidator(issuer, jwt, validationParameters);
    }
    else
    {
    issuer = ValidateIssuer(issuer, jwt, validationParameters);
    }
    }

    if (validationParameters.ValidateActor && !string.IsNullOrWhiteSpace(jwt.Actor))
    {
    SecurityToken actor = null;
    ValidateToken(jwt.Actor, validationParameters, out actor);
    }

    ClaimsIdentity identity = this.CreateClaimsIdentity(jwt, issuer, validationParameters);
    if (validationParameters.SaveSigninToken)
    {
    identity.BootstrapContext = new BootstrapContext(securityToken);
    }

    validatedToken = jwt;
    return new ClaimsPrincipal(identity);
    }

    Reply
    • Taiseer Joudeh says

      December 24, 2015 at 12:51 am

      Thanks for sharing this, really appreciated, I never digged too deep in the implementation of the JWTTokenSecurityHandler. I just replied on your SO comment but things are clear now. Thanks again for sharing this.

      Reply
    • Rafael de Oliveira says

      January 8, 2016 at 2:56 am

      Good evening, I’m going through the same problem and also to days.
      I’m sorry for my basic English.

      I followed his comment but did not understand where I add these lines of code. Which of the classes created in the tutorial I add them? I create new classes?

      I await their return and since I thank you for your attention.
      Thanks,

      Rafael de Oliveira.

      Reply
  75. Bo Stokholm says

    December 22, 2015 at 1:07 pm

    Hi
    Great tutorial. I do just have one problem. When I login I get the token but when I try to pass the token to changepassword api then I get a 401. It is like it doesn’t even try to validate the token?

    I have made a stackoverflow ticket on it: https://stackoverflow.com/questions/34405490/web-api-giving-401-on-jwt
    Hope you can help.

    Reply
    • Taiseer Joudeh says

      December 23, 2015 at 6:29 pm

      Hi,
      Is this happening only for this endpoint or you are receiving 401 on other endpoints attribute with [Authorize] attribute?

      Reply
    • treetopvt says

      December 23, 2015 at 6:58 pm

      I’ve posted a potential solution over on StackOverflow and otherplaces on this Blog, but you basically want to create your own JWTTokenHandler that derives from JWTSecuirityTokenHandler. This will at least let you ‘open the hood’ and see why your token is failing Authorization.

      Reply
      • Felix Rabinovich says

        January 24, 2016 at 11:45 pm

        I think I figured out what the problem is… issued should be in local time and not in UTC. I put a longer reply with code snippets in the same StackOverflow post.

        Reply
  76. Christopher McCrum says

    December 24, 2015 at 6:56 am

    Hey Taiseer, I was wondering if you’ll be offering a write up for ASP NET 5? Your walkthrough has worked flawlessly for us in our older project. I’m currently trying to implement it but I’ve notice quite a bit has changed. thanks again for all your hard work!

    Reply
    • Taiseer Joudeh says

      December 24, 2015 at 10:55 pm

      Hi Chris,
      I’m just waiting for RC 2 as the ASP.NET team keeps breaking some methods which each release, as well the Identity and token issue still not clear in ASP.NET 5 yet, there is no built in middleware to issue access token in ASP.NET 5. Maybe I will use the external IdSrv3 or Open Id connection middleware to do this task.

      Reply
  77. alexstrakh says

    January 11, 2016 at 10:51 am

    Excellent explanation and it works fine. One issue here is that when the token is invalid or not specified I’m getting 404 (NotFound) instead of 401 (NotAuthorized). I configured my OAuth exactly like you described here. What could be wrong?

    Reply
    • Taiseer Joudeh says

      January 17, 2016 at 11:48 am

      Hi Alex, sorry for the late reply.
      Did you find solution for your issue? I never faced such issue when the API returns 404 when it is unauthorized.

      Reply
      • alexstrakh says

        January 17, 2016 at 11:06 pm

        I have noticed that if I also getting redirect to Login.aspx even though I disabled forms auth in web.config.
        It seems that after publishing to azure forms auth module continue to work. I found similar issue here and as one of solution is to remove that module:

        http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx/

        Reply
  78. Leo says

    February 2, 2016 at 11:01 pm

    Hey Taiseer, I am making a call web api in order to authenticate users from asp.net application

    private static async Task GetAPIToken(string userName, string password, string apiBaseUri)
    {
    using (var client = new HttpClient())
    {
    //setup client
    client.BaseAddress = new Uri(apiBaseUri);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(“application/json”));

    //setup login data
    var formContent = new FormUrlEncodedContent(new[]
    {
    new KeyValuePair(“grant_type”, “password”),
    new KeyValuePair(“username”, userName),
    new KeyValuePair(“password”, password),
    });

    //send request
    HttpResponseMessage responseMessage = await client.PostAsync(“/Token”, formContent);

    //get access token from response body
    var responseJson = await responseMessage.Content.ReadAsStringAsync();
    var jObject = JObject.Parse(responseJson);
    return jObject.GetValue(“access_token”).ToString();
    }
    }

    The PostAsync is executed successfully on the web api but I could not get the response message in my web application.

    Any ideas ?

    Thanks in advance,

    Leo

    Reply
    • Tomasz Jagusz says

      April 26, 2016 at 3:21 pm

      @Leo did You manage to solve this? I need to do something similar. Thanks for reply.

      Reply
  79. espinojmanu says

    February 8, 2016 at 10:19 pm

    Hi Taiseer

    Again, thanks a lot for this tutorial but I’m a little bit confused and I hope you could help me.

    In a real-life situation, should I validate my client app in ValidateClientAuthentication method inside CustomOAuthProvider class? or it is enough with the AudienceId and AudienceSecret or I’m totally confused?.

    In addition, Audience ID could be any string (e.g. ‘My App’) just with HMAC265, same for the Audience secret?.

    Reply
    • Raj says

      September 26, 2016 at 5:26 pm

      Drop this into a windows form with a button and a textbox for the result…

      using System;
      using System.Windows.Forms;
      using Microsoft.Owin.Security.DataHandler.Encoder;
      using System.Security.Cryptography;

      namespace GenSecret
      {
      public partial class Form1 : Form
      {
      public Form1()
      {
      InitializeComponent();
      }

      private void Form1_Load(object sender, EventArgs e)
      {

      }

      private void button1_Click(object sender, EventArgs e)
      {
      var clientId = Guid.NewGuid().ToString(“N”);

      var key = new byte[32];
      RNGCryptoServiceProvider.Create().GetBytes(key);
      var base64Secret = TextEncodings.Base64Url.Encode(key);

      textBox2.Text = string.Format(“Client Id: {0}\r\n\r\nSecret: {1}”, clientId, base64Secret);
      }
      }
      }

      Reply
  80. Seng Joon says

    February 14, 2016 at 6:03 pm

    Help Need. The system works well with create user, delete user, list all the users. however, it fail to obtain token. even i supplied the right username and password, it continue give me error message invalid_grant. I use debugger to trace, and found ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password); return a Null value.

    Exception:Caught: “Could not load file or assembly ‘Microsoft.VisualStudio.Web.PageInspector.Runtime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specified.” (System.IO.FileNotFoundException)
    A System.IO.FileNotFoundException was caught: “Could not load file or assembly ‘Microsoft.VisualStudio.Web.PageInspector.Runtime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. The system cannot find the file specified.”
    Time: 14/02/2016 10:50:51 PM
    Thread:[28136]

    Any Idea what could be wrong?

    Reply
    • Taiseer Joudeh says

      February 16, 2016 at 6:35 am

      Maybe this answer will help you

      Reply
  81. shengqisong says

    February 18, 2016 at 9:40 pm

    This is the best tutorial that I can found. I have a error in the last step, it says: JwtSecurityTokenHandler.cs not found. Do I need to create this class? Thanks for your help.

    Reply
    • Taiseer Joudeh says

      February 22, 2016 at 12:29 pm

      Download the source code from GitHub and check if this class is created or from NuGet package.

      Reply
  82. kapacoo says

    February 19, 2016 at 7:33 am

    calling time –> http://localhost:59822/oauth/token
    actionfilter , DelegatingHandler not working

    Reply
  83. napster0908 says

    February 20, 2016 at 3:43 pm

    Hi,

    I tried your solution on azure and it works perfectly. However when I try your solution on another server I get the notification below. It only happens on the first login attempt. The second, right after the first, works perfectly. Any idea on what could be causing this?

    XMLHttpRequest cannot load https://api-address/oauth/token. Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘https://client-address’ is therefore not allowed access. The response had HTTP status code 400.

    Reply
    • Taiseer Joudeh says

      February 22, 2016 at 12:16 pm

      I’m not sure why this is happening, but I recall I faced the same issue and we discussed it on the comments section for this post. Can you please check this answer

      Reply
      • napster0908 says

        February 22, 2016 at 12:38 pm

        This is exactly the solution which helped me. Unfortunately I found it out myself yesterday. After I placed the usecors on top an error in my application log started to arise regarding duplicate ‘Access-Control-Allow-Origin’. After removing the line in the article you send it disappeared. Thanks for your reply though 🙂

        Reply
  84. Amol Kulkarni says

    February 22, 2016 at 10:43 am

    Hi

    This is an excellent article.

    here is one issue I am facing , in the GrantResourceOwnerCredentials if the user is not found either because of wrong username or password , A set error method is called

    if (user == null)
    {
    context.SetError(“invalid_grant”, “The user name or password is incorrect.”);
    return;
    }

    In the above situation the HttpStatus code is always set to 400 (bad request) . I have tried various approaches but could not set the HttpStatus code to 401. Do you know if there is a way to do it ? I have been struggling with this for some time now.

    Reply
    • Taiseer Joudeh says

      February 22, 2016 at 11:40 am

      Hi Amol,

      Returning 400 is the correct http status in this case, and this based OAuth 2.0 specs, the user is not authenticated yet and he is providing incorrect username/password so he he is providing incorrect data from the client, so 400 is correct. You should return 401 if the user was already authenticated (has an access token) and this token is expired or invalid anymore.

      Reply
  85. Ole H says

    February 28, 2016 at 9:37 pm

    Hi.
    Thank you for these posts, they make a very difficult subject comprehensible.

    However I am still a bit confused in what the difference is between the tutorial here on this page, where we are issuing
    JWT tokens with oauth insted of “default access tokens” and the tutorial in this 5 part series where we are issuing “OAuth Bearer Tokens”:

    https://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/

    As I understand both these tokens are fully self-contained, and there is no corresponding session on the server for any of them, so what is actually the practical difference between issuing and using these two type of tokens?

    Is it just that you can decouple Authorization server from Resource server with JWT?

    Thanks!

    Reply
    • Taiseer Joudeh says

      March 3, 2016 at 11:56 pm

      Hi Ole,

      The tutorial here is using Bearer tokens as the post here too, the difference only relies on the access token format, the JWT tokens are signed only (not encrypted) and you can decode the claims in the client side application, you can use JWT.io to decode the JWT and see the claims, on the other side, the JWT format is becoming the more standard way of sending OAuth 2.0 bearer tokens.
      Hope this answers your question.

      Reply
  86. Simon says

    March 15, 2016 at 2:30 pm

    I echo all the thanks, these tutorials are a little bit vital !

    I (too) am mystified when you say the Angular front end is a “trusted client”. How is it trusted? How is it even identified (authenticated)?

    Reply
  87. Ole H says

    March 16, 2016 at 2:56 pm

    Thank you for your reply. I just have one more questions.
    I want to add login and registration with external provider (facebook, google) to the application.
    Can I use the guide you have provided here (https://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/) as-is, or do I have to make some changes to that code now that I have configured the app to use JWT ?

    Thanks.

    Reply
  88. Ole H says

    March 22, 2016 at 6:26 pm

    To answer my own question: The guide on implementing facebook/google login can be used pretty much as-is if you have followed the guide on this page to issue and consume json web tokens, but some small changes was required. Here is what I changed:

    In the first guide you set OAuthBearerAuthenticationOptions as a static member of Owin Startup class and later call
    app.UseOAuthBearerAuthentication(OAuthBearerOptions) as shown in the code here: https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.API/Startup.cs#l54

    Skip that part. Instead you set OAuthAuthorizationServerOptions as a static member of Startup class, then you just follow the guide on this page (initialize it and call app.UseOAuthAuthorizationServer(OAuthServerOptions) ). You also have to call
    “app.UseExternalSignInCookie(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ExternalCookie);” as explained in the first guide. https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.API/Startup.cs#l40

    Then you can generate a similar JWT as in path ”http://localhost:59822/oauth/token” in method GenerateLocalAccessTokenResponse in AccountController.

    here is my code:

    At the end In method “RegisterExternal” and “ObtainLocalAccessToken”:

    […]
    ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager, “JWT”);
    var accessTokenResponse = GenerateLocalAccessTokenResponse(oAuthIdentity);

    return Ok(accessTokenResponse);

    private JObject GenerateLocalAccessTokenResponse(ClaimsIdentity oAuthIdentity) {

    TimeSpan tokenExpiration = TimeSpan.FromMinutes(Convert.ToDouble(ConfigurationManager.AppSettings[“JWTExpirationTimeInMinutes”]));

    var props = new AuthenticationProperties() {
    IssuedUtc = DateTime.UtcNow,
    ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
    };

    var ticket = new AuthenticationTicket(oAuthIdentity, props);

    var accessToken = Startup.OAuthServerOptions.AccessTokenFormat.Protect(ticket);

    JObject tokenResponse = new JObject(
    new JProperty(“access_token”, accessToken),
    new JProperty(“expires_in”, tokenExpiration.TotalSeconds.ToString()),
    new JProperty(“token_type”, “bearer”));

    return tokenResponse;
    }

    Thanks again to Taiseer Joudeh for these guides!

    Reply
    • Taiseer Joudeh says

      March 24, 2016 at 12:05 pm

      You are most welcome, and thanks for sharing the answer and your thoughts.

      Reply
  89. Nav says

    April 6, 2016 at 1:32 am

    This is a great article. I understand that we are leveraging the default [Authorize] Attribute. I want to create a custom Authorize Attribute with custom logic to deal with my authentication. When I create one I am noticing that the app.UseJwtBearerAuthentication does not execute and I can pass in invalid json web tokens. Is there a way to configure UseJwtBearerAuthentication to use a custom authorize attribute after it is done validating the token?

    Thanks

    Reply
  90. Tomasz Jagusz says

    April 26, 2016 at 3:31 pm

    @Taiseer again great article. I’m still learning new things from whole serie. I got use case that I’m trying to solve, but for now I’m stuck.

    I’m creating new user using CreateUser method, but instead new user object I’d like to return JWT token. Idea is to remove that extra call that is required to sign-in. In other words I’d like to return token so when user account is created he can already do API calls without need to sign-in.

    Can this be done? I found some code by @Leo (https://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-and-identity-2/comment-page-2/#comment-73830) but it requires creating HttpClient and I’d like to avoid that.

    Reply
    • Taiseer Joudeh says

      April 27, 2016 at 1:46 am

      Hi Tomasz,
      I got your question, you need to register a user then directly generate a token without doing a login, so what you trying to achive is to generate a token inside a controller, please check this SO answer, it might be useful.

      Reply
  91. Graeme Downes says

    May 2, 2016 at 3:31 pm

    Hi Taiseer

    Great series, I’ve used your tutorials to setup jwt oauth flows for many projects.

    Recently I’ve been concerned about storing token data in browser local storage and I’m trying to instead keep the jwt token encrypted in an http only cookie (for the web clients)

    Is there a natural extension to the approach you’ve discussed whereby I can both store the token in an httponly cookie and handle the refresh token flow without the client explicitly making a call to refresh?

    Thanks
    Graeme

    Reply
    • Taiseer Joudeh says

      May 5, 2016 at 11:06 am

      Hi Graeme,

      You can check the ThinkTecture Identity where they have helpers to do this, I didn’t try this but I remember I watched Brock doing a demo while he was able to refresh tokens using Identity Model.

      Hope this helps.

      Reply
  92. Mady says

    May 11, 2016 at 10:48 am

    Hi Taiseer,

    Wonderful articles on Oauth. I want to implement OAuth 2.0 using MAC token and not Bearer token as I am interested to use SSL along with OAuth. Can you please guide me to implement the same.

    Thanks,
    Mady

    Reply
  93. John Snyder says

    May 12, 2016 at 1:02 am

    Hi Taiseer,

    I downloaded the source code you posted and then, using Visual Studio 2015, I opened the solution. It built just fine, but when I run it:
    1) The Configuration method of the Startup class is never called;
    2) Any attempt (with Postman) to get a token at http://localhost:59822/auth/token results in a 404 error.

    Can you advise on how I can figure out what the problem is?

    Thanks so much!

    Reply
  94. John Snyder says

    May 12, 2016 at 3:09 am

    Hi Taiseer,

    I’m still not sure why your solution is not working correctly in my local environment, but I have implemented the key portions in my primary test project, which is working, so please don’t spend any time working on it.

    Thanks for everything – your articles are great!

    — John

    Reply
    • Taiseer Joudeh says

      May 23, 2016 at 11:18 am

      You are welcome and sorry for the late reply 🙂

      Reply
  95. ganeshkumaresan says

    May 20, 2016 at 10:34 am

    Hi Taiseer,

    Is it possible to use only OAuth security without Asp.Net identity or OWIN but my own membership functionality???

    Reply
    • Taiseer Joudeh says

      May 23, 2016 at 11:10 am

      Sure thing, you can use it with any DB provider you want, not only SQL. ASP.NET Identity for managing users and has nothing to do with OAuth security.

      Reply
  96. r3plica0 says

    May 27, 2016 at 12:42 pm

    I have read your posts and they are great. I have tried implementing this in my own application and when I come to use Postman to the oauth/token endpoint I am getting the same error every time:

    {
    “error”: “invalid_client”
    }

    Can you think of any reason why I would be getting this?
    Also, the audienceId and audienceSecret have me confused. I looked at the way you were generating them and it looks like the secret is just base64 encoded id, is that correct?

    Reply
  97. Dan says

    June 18, 2016 at 2:23 am

    Hi,

    The articles are excellent. Thank you very much for all your effort.

    I have been scratching my head on this one….. I downloaded your project from Git and compiled it ok. I run and test the oauth/token endpoint and my context within this method is always null for the username and password in the context. Have you seen this before?

    File: AspNetIdentity.WebApi.Providers.CustomOAuthProvider

    Method: GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

    Line: ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);

    Issue: context.UserName and context.Password are null

    Kind regards
    Dan

    Reply
    • Taiseer Joudeh says

      June 18, 2016 at 6:27 pm

      Hi Dan,
      You need to make sure your sending the request using the correct content-type, it should not be JSON, it should be “x-www-form-urlencoded”
      Hope it helps.

      Reply
      • Dan Bambling says

        June 20, 2016 at 12:53 am

        Hi,

        thanks for the reply. This is what I was wondering however I have double checked and know (believe) that I am passing the correct content-type.

        Please see request below from fiddler.

        POST http://localhost:52212/oauth/token HTTP/1.1
        Host: localhost:52212
        User-Agent: Mozilla/5.0 (Windows NT 6.2; rv:47.0) Gecko/20100101 Firefox/47.0
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
        Accept-Language: en-US,en;q=0.5
        Accept-Encoding: gzip, deflate
        Content-Type: application/x-www-form-urlencoded
        Authorization: Basic dGVzdEB0ZXN0LmNvbTp0ZXN0MjM0ISI=
        Content-Length: 19
        Connection: keep-alive

        grant_type=password

        It is really weird. Not sure why this is as I cannot seem to obtain any relevant information as to why the context has nulls in it.

        Any other suggestions? Would it be that I have updated the assemblies due to nuget update?

        Kind regards
        Dan

        Reply
  98. Abhijit Ajmera says

    June 28, 2016 at 10:26 am

    I have an Android App talking to an ASP.NET Web API back-end. Android app offers SignIn with email address or SignIn with Google.

    I am using Google’s SDK for rich SignIn experience i.e. user doesn’t need to provide credentials and directly opens rich dialog for authorization. I am able to get the access token and user profile. So far so good.

    Coming to ASP.NET Web API external authentication. I understand that once I have access token, most likely the following needs to happen:

    Android app calls Web API with Access Token to do ExternalSignIn
    Web API processes the request and returns bearer token of SignedIn user.
    validates access token
    obtains user’s login info from Google
    check for existing local user. If not found, create one.
    Generate bearer token for the local user (newly created or existing one)
    Return it to the caller
    Web API can now use bearer token to call protected APIs.
    I have been studying OWIN Auth Server and all the auth/authz code that ASP.NET creates for external social accounts, it seems it is assuming app will use web flow for Google Sign-In and there will be auth cookie set by the Google OWIN middleware.

    I have searched a lot, but couldn’t find any good pointers on how to do it efficiently by using ASP.NET’s built-in support for Google sign in.

    Worst case, the alternative that I have in my mind is:

    Create a Web API ExternalSignIn(string accessToken)
    In the Web API, pretty much do what I mentioned above.

    Reply
  99. Abhijit Ajmera says

    June 28, 2016 at 10:29 am

    I have an Android App talking to an ASP.NET Web API back-end. Android app offers SignIn with email address or SignIn with Google.

    I am using Google’s SDK for rich SignIn experience i.e. user doesn’t need to provide credentials and directly opens rich dialog for authorization. I am able to get the access token and user profile. So far so good.

    Coming to ASP.NET Web API external authentication. I understand that once I have access token, most likely the following needs to happen:

    1. Android app calls Web API with Access Token to do ExternalSignIn
    2. Web API processes the request and returns bearer token of SignedIn user.
    2.1 validates access token
    2.2 obtains user’s login info from Google
    2.3 check for existing local user. If not found, create one.
    2.4 Generate bearer token for the local user (newly created or existing one)
    2.5 Return it to the caller
    3. Web API can now use bearer token to call protected APIs.

    I have been studying OWIN Auth Server and all the auth/authz code that ASP.NET creates for external social accounts, it seems it is assuming app will use web flow for Google Sign-In and there will be auth cookie set by the Google OWIN middleware.

    I have searched a lot, but couldn’t find any good pointers on how to do it efficiently by using ASP.NET’s built-in support for Google sign in.

    Worst case, the alternative that I have in my mind is to create a web api that does external sign in with access tokens by doing the above 1-3.

    Reply
Newer Comments »

Trackbacks

  1. OAuth JWT access token expiration depending on type of client | FYTRO SPORTS says:
    May 15, 2015 at 5:07 pm

    […] I created a JWT token implementation based on Taiseer’s tutorial. […]

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About Taiseer

Husband, Father, Consultant @ MSFT, Life Time Learner... Read More…

Buy me a coffeeBuy me a coffee

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Blog Archives

Recent Posts

  • Integrate Azure AD B2C with ASP.NET MVC Web App – Part 3
  • Secure ASP.NET Web API 2 using Azure AD B2C – Part 2
  • Azure Active Directory B2C Overview and Policies Management – Part 1
  • ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1 – Part 5
  • ASP.NET Identity 2.1 Roles Based Authorization with ASP.NET Web API – Part 4

Tags

AJAX AngularJS API API Versioning ASP.NET Authentication Autherization Server Azure Active Directory B2C Azure AD B2C basic authentication C# CacheCow Client Side Templating Code First Dependency Injection Entity Framework ETag Foursquare API HTTP Caching HTTP Verbs IMDB API IoC Javascript jQuery JSON JSON Web Tokens JWT Model Factory Ninject OAuth OData Pagination Resources Association Resource Server REST RESTful Single Page Applications SPA Token Authentication Tutorial Web API Web API 2 Web API Security Web Service wordpress.com

Search

Copyright © 2021 · eleven40 Pro Theme on Genesis Framework · WordPress · Log in

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.