Securing MongoDB Access with Username and Password

My MongoDb journey continues :) and I had my first attempt to put a username and password protection against a MongoDB instance. It went OK besides some hiccups along the way :) Let's see what I did.
2014-05-01 10:44
Tugberk Ugurlu


My MongoDb journey continues :) and I had my first attempt to put a username and password protection against a MongoDB instance. It went OK besides some hiccups along the way :) Let's see what I did.

First, I downloaded the latest (v2.6.0) MongoDB binaries as zip file and unzipped them. I put all MongoDB related stuff inside the c:\mongo directory for my development environment on windows and the structure of my c:\mongo directory is a little different:

Screenshot 2014-04-30 13.50.16

In order to set up the username and password authentication, first I need to get the mongod instance up and running with the authorization on. I achieved that by configuring it with the config file. Here is how it looks like:

dbpath = c:\mongo\data\db
port = 27017
logpath = c:\mongo\data\logs\mongo.log
auth = true

With this config file in place, I can get the mongod instance up:

image

First, I need to connect to this mongod instance and create the admin user. As you can see inside my config file, the server requires authentication. However, there is a localhost exception if there is no user defined inside the system. So, I can connect to my instance anonymously (as I’m running on port 27017 on localhost, I don’t need to define anything while firing up the mongo shell):

image

All great! Let’s create the system user administrator. As everything else, this chore is nicely documented, too:

use admin
db.createUser(
  {
    user: "tugberk",
    pwd: "12345678",
    roles:
    [
      {
        role: "userAdminAnyDatabase",
        db: "admin"
      }
    ]
  }
)

We are pretty much done. We have a user to administer our server now. Let’s disconnect from the mongo shell and reconnect to our mongod instance with our credentials:

mongo --host localhost --port 27017 -u tugberk -p 12345678 --authenticationDatabase admin

image

I’m all there and I can see what my privileges at the server with this user are.

If you try to connect to this MonogDB server anonymously, you will see that you are still able to connect to it. This’s really bad, isn’t it? Not at the level that you think it would be at. The real story is that MongoDB still allows you to connect to, but you won’t be able to do anything as the anonymous access is fully disabled.

image

The bad thing here is that your server existence is exposed which is still an important issue. Just be aware of this fact before getting started.

The user we created still has restricted access to MonogDB server. If you want to have a user with unrestricted access, you can create a user with root role assigned. In our case here, I will assign myself the root role:

use admin
db.grantRolesToUser("tugberk", ["root"])

Resources

Challenge of Solving an ASP.NET Web API Self-Hosting Problem: No HTTP resource was found that matches the request URI

Couple of weeks ago, one of my former coworkers ran across a very weird problem when he was prototyping on some of his ideas with ASP.NET Web API: No HTTP resource was found that matches the request URI. Let's see what this issue was all about and what is the solution.
2014-04-16 08:28
Tugberk Ugurlu


Couple of weeks ago, one of my former coworkers ran across a very weird problem when he was prototyping on some of his ideas with ASP.NET Web API. He was hosting his ASP.NET Web API application on a console application using the Microsoft.Owin.Hosting components and Microsoft.Owin.Host.HttpListener host. His solution structure was also very simple. He put all of his controllers, message handlers, filters, etc. in one class library and all the hosting logic inside the console application. The below structure was pretty similar to what he did:

Screenshot 2014-04-16 10.36.01

Console application also has very little amount of code:

class Program
{
    static void Main(string[] args)
    {
        using (WebApp.Start("http://localhost:5555/", Start))
        {
            Console.WriteLine("Started listening on localhost:5555");
            Console.ReadLine();
            Console.WriteLine("Shutting down...");
        }
    }

    static void Start(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");
        app.UseWebApi(config);
    }
}

As you can see, it's all done by the book. However, he was constantly getting 404 when he fired up the application and sent a request to /api/cars:

Screenshot 2014-04-16 10.41.50

"No HTTP resource was found that matches the request URI". It's pretty strange. After I looked into the issue for a while, I was able to figure what the problem is:

Screenshot 2014-04-16 10.45.50

Let's make this a little bit interesting and have a look at the modules loaded into the AppDomain :)

Screenshot 2014-04-16 10.49.30

Notice that the WebApiStrangeConsoleHostSample.dll was never loaded into the AppDomain because we never used it even if it's referenced. As ASP.NET Web API uses reflection to determine the controller and the action, it never finds the CarsController. To prove our point here, I'll load the assembly manually:

static void Main(string[] args)
{
    Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, "WebApiStrangeConsoleHostSample.dll"));
    using (WebApp.Start("http://localhost:5555/", Start))
    {
        Console.WriteLine("Started listening on localhost:5555");
        Console.ReadLine();
        Console.WriteLine("Shutting down...");
    }
}

The result is a success:

Screenshot 2014-04-16 10.56.56

However, this is not an ideal solution and I bet that you never run into this issue before. Why? Because, you wise developer keep your hosting agnostic bootstrap code inside the same assembly with you core ASP.NET Web API layer and you call this inside the host application. As soon as you call a method from the core layer assembly, that assembly will be loaded into your AppDomain.

public static class WebApiConfig
{
    public static void Configure(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute("DefaultHttpRoute", "api/{controller}");
    }
}
class Program
{
    static void Main(string[] args)
    {
        using (WebApp.Start("http://localhost:5555/", Start))
        {
            Console.WriteLine("Started listening on localhost:5555");
            Console.ReadLine();
            Console.WriteLine("Shutting down...");
        }
    }

    static void Start(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Configure(config);
        app.UseWebApi(config);
    }
}

There is one other potential solution to a problem which is similar to this one. That is to replace the IAssembliesResolver service as Filip did in this post.

Order of Fields Matters on MongoDB Indexes

Order of Fields Matters on MongoDB Indexes. Let's see how with an example.
2014-04-12 18:52
Tugberk Ugurlu


As my MongoDB journey continues, I discover new stuff along the way and one of them is about indexes in MongoDB. Let me try to explain it with a sample.

First, create the below four documents inside our users collection:

db.users.save({ 
	_id: 1, 
	name: "tugberk1", 
	login: [
		{ProviderName: "twitter", ProviderKey: "232"}, 
		{ProviderName: "facebook", ProviderKey: "423"}
	]
});
	
db.users.save({ 
	_id: 2, 
	name: "tugberk23", 
	login: [
		{ProviderName: "twitter", ProviderKey: "3443"}
	]
});

db.users.save({ 
	_id: 3, 
	name: "tugberk4343", 
	login: [
		{ProviderName: "dropbox", ProviderKey: "445345"}
	]
});

db.users.save({ 
	_id: 4, 
	name: "tugberk98", 
	login: [
		{ProviderName: "dropbox", ProviderKey: "3443"}, 
		{ProviderName: "facebook", ProviderKey: "768"}
	]
});

Let’s query the users collection by login.ProviderKey and login.ProviderName:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).pretty();

image

It found the document we wanted. Let’s see how it performed:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).explain();

image

Result is actually pretty bad. It scanned all four documents to find the one that we wanted to get. Let’s put an index to ProviderName and ProviderKey fields:

db.users.ensureIndex({
	"login.ProviderName": 1, 
	"login.ProviderKey": 1
});

Now, let’s see how it performs the query:

image

It’s better as it scanned only two documents. However, we had only one matching document for our query. As the chances that the providerKey will be more unique than the ProviderName, I want it to first look for the ProviderKey. To do that, I need to change the index:

db.users.dropIndex({
	"login.ProviderName": 1, 
	"login.ProviderKey": 1 
});
db.users.ensureIndex({ 
	"login.ProviderKey": 1, 
	"login.ProviderName": 1 
});

Let’s now see how it’s trying to find the matching documents:

db.users.find({
	"login.ProviderKey": "232", 
	"login.ProviderName": "twitter"
}).explain();

image

Boom! Only one document was scanned. This shows us how it’s important to put the fields in right order for our queries.

Resources

A C# Developer's First Thoughts on MongoDB

After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :)
2014-04-12 14:22
Tugberk Ugurlu


After working with RavenDB over the year, I just started looking into MongoDB. I worked with MongoDB a year ago or so in a small project but my knowledge was mostly rusty and I don't want that to happen again :) So, here I'm, documenting what my second thoughts are :) The TL;DR is that: I'm loving it but the lack of transaction sometimes drifts on a vast dark sea. It's OK through. The advantages generally overcomes this disadvantage.

Loved the Mongo Shell

First thing I liked about MongoDB is its shell (Mongo Shell). 

3d6f5fdd4be53096b6992d5b84b0d7be

It makes it insanely easy for you to get used to MongoDB. After running the mongod.exe, I fired up a command prompt and navigated to mongo.exe directory and entered the mongo shell. Mongo Shell runs pure JavaScript code. That's right! Anything you know about JavaScript is completely valid inside the mongo shell. Let's see a few things that you can do with mongo shell.

You can list the databases on your server: show dbs

2

You can see which database you are connected to: db

3

You can switch to a different database: use <database name here>

4

You can see the collections inside the database you are on: show collections

5

You can save a document inside a collection: db.users.save({ _id: "tugberk", userName: "Tugberk" })

6

You can list the documents inside a collection: db.users.find().pretty()

7

You can run a for loop:

for(var i = 0; i < 10; i++) { 
	db.users.save({ 
		_id: "tugberk" + i.toString(), 
		userName: "Tugberk" + i.toString() 
	}) 
}

8

You can run the code inside a js file

9

saveCount.js contains the following code and it just gets the count of documents inside the users collection and logs it inside another collection:

(function() {
     var myDb = db.getSiblingDB('myDatabase'),
         usersCount = myDb.users.find().count();
         
     myDb.countLogs.save({
          count: usersCount,
          createdOn: new Date()
     });
}());

All of those and more can be done using the mongo shell. It's a full blown MongoDB client and probably the best one. I don't know if it's just me but big missing feature of RavenDB is this type of shell.

Loved the Updates

Update operations in MongoDB is just fabulous. You can construct many kinds of updates, the engine allows you to do this fairly easily. The one I found most useful is the increment updates. Increment updates allows you to increment a field and this operation will be performed concurrency in-mind:

db.books.update(
   { item: "Divine Comedy" },
   {
      $inc: { stock: 5 }
   }
)

The above query will update the stock filed by 5 safely.

Not much Love for the .NET Client

MongoDB has an official .NET client but MongoDB guys decided to call this "C# driver". This is so strange because it works with any other .NET languages as well. I have to say that MongoDB .NET client is not so great in my opinion. After coming from the RavenDB .NET client, using the MongoDB .NET client just feels uncomfortable (However, I’m most certainly sure that I’d love its Node.Js client as it would feel very natural).

First of all, it doesn't support asynchronous requests to MongoDB server. All TCP requests are being done synchronously. Also, there is no embedded server support. RavenDB has this and it makes testing a joy. Let's look at the below code which gets an instance of a database:

MongoClient client = new MongoClient("mongodb://localhost");
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase("mongodemo");

There is too much noise going on here. For example, what is GetServer method there? Instead, I would want to see something like below:

MongoClient client = new MongoClient("mongodb://localhost");
using(var session = client.OpenSession("myDatabase"))
{
     // work with the session here...
}

Looks familiar :) I bet it does! Other than the above issues, creating map/reduce jobs just feels weird as well because MongoDB supports JavaScript to perform map/reduce operations.

var map =
    "function() {" +
    "    for (var key in this) {" +
    "        emit(key, { count : 1 });" +
    "    }" +
    "}";

var reduce =
    "function(key, emits) {" +
    "    total = 0;" +
    "    for (var i in emits) {" +
    "        total += emits[i].count;" +
    "    }" +
    "    return { count : total };" +
    "}";

var mr = collection.MapReduce(map, reduce);
foreach (var document in mr.GetResults()) {
    Console.WriteLine(document.ToJson());
}

The above code is directly taken from the MongoDB documentation.

Explore Yourself

MongoDB has a nice documentation and you can explore it yourself. Besides that, Pluralsight has a pretty nice course on MongoDB: Introduction to MongoDB by Nuri Halperin. Also, don't miss the Ben's post on the comparison of Map-Reduce in MongoDB and RavenDB.

Simple OAuth Server: Implementing a Simple OAuth Server with Katana OAuth Authorization Server Components (Part 1)

In my previous post, I emphasized a few important facts on my journey of building an OAuth authorization server. As great people say: "Talk is cheap. Show me the code." It is exactly what I'm trying to do in this blog post. Also, this post is the first one in the "Simple OAuth Server" series.
2014-04-01 14:30
Tugberk Ugurlu


In my previous post, I emphasized a few important facts on my journey of building an OAuth authorization server. As great people say: "Talk is cheap. Show me the code." It is exactly what I'm trying to do in this blog post. Also, this post is the first one in the "Simple OAuth Server" series.

What are We Trying to Solve Here?

What we want to achieve at the end of the next two blog posts is actually very doable. We want to have a console application where we handle calls to our protected web service endpoints and access them in a delegated manner which means that the client will actually access the resources on behalf of a user (in other words, resource owner). However, we won't be accessing the web service with resource owner's credentials (username and password). Instead, we will use the credentials to obtain an access token through the resource owner credentials grant and use that token to access the resources from that point on. After this blog post, we will expend our needs and build on top of our existing solution with the upcoming posts. That's why this post will be a little bit detailed about how you could set up the project and we will only cover building the OAuth server part.

Building the Application Infrastructure

I'll start by creating the ASP.NET Web API application. As mentioned, our application will evolve over time with the upcoming posts. So, this post will only cover the minimum requirements. So, bare this in mind just in case. I used the provided project templates in Visual Studio 2013 to create the project. For this blog post content, we only need ASP.NET Web API components to create our project.

Screenshot 2014-03-31 11.19.58 

Screenshot 2014-03-31 11.22.19

At the time of writing this post, visual Studio 2013 had the old ASP.NET Web API bits and it's worth updating the package before we continue:

Screenshot 2014-03-31 11.26.09

The OAuth authorization server and the ASP.NET Web API endpoints will be hosted inside the same host in our application here. In your production application, you would probably don't want to do this but for our demo purposes, this will be simpler.

Now we are ready to build on top of the project template. First thing we need is a membership storage system. Nothing would be better than new ASP.NET Identity components. I will use the official Entity Framework port of the ASP.NET Identity for our application here. However, you are free to choose your own data storage engine. Scott Allen has a great blog post about the extensibility of ASP.NET Identity and he listed available open source projects which provide additional storage options for ASP.NET Identity such as AspNet.Identity.RavenDB.

Screenshot 2014-03-31 11.36.12

There are two more packages that you need to install. One of them is Microsoft.AspNet.Identity.Owin. This package provides several useful extensions you will use while working with ASP.NET Identity on top of OWIN. The other one is Microsoft.Owin.Host.SystemWeb package which enables OWIN-based applications to run on IIS using the ASP.NET request pipeline.

The packages we just installed (Microsoft.AspNet.Identity.Owin) also brought down some other packages as its dependencies. One of those dependency packages is Microsoft.Owin.Security.OAuth and this is the core package that includes the components to support any standard OAuth 2.0 authentication workflow. Just wanted to highlight this fact as this is an important part of the project.

I will create the Entity Framework DbContext which will hold membership and OAuth client data. ASP.NET Identity Entity Framework package already has the DbContext implementation for the membership storage and our context class will be derived from that.

public class OAuthDbContext : IdentityDbContext
{
    public OAuthDbContext()
        : base("OAuthDbContext")
    {
    }

    public DbSet<Client> Clients { get; set; }
}

OAuthDbContext class is derived from IdentityDbContext class as you see. Also notice that we have another DbSet property for clients. That will represent the information of the clients. The Client class is a shown below:

public class Client
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string ClientSecretHash { get; set; }
    public OAuthGrant AllowedGrant { get; set; }

    public DateTimeOffset CreatedOn { get; set; }
}

This is the minimum that we need from the client to register in our authorization server. For certain grants, the client doesn't need to have a secret but for "Resource Owner Password Credentials Grant", it's mandatory. The client is also allowed for only one grant, that's all. This is not inside the OAuth 2.0 specification but it's the recommended approach. OAuthGrant is an enum and has the following values:

public enum OAuthGrant
{
    Code = 1,
    Implicit = 2,
    ResourceOwner = 3,
    Client = 4
}

These are all we need for now and we are ready to create the database. I will use Entity Framework Migrations feature to stand up the database and seed some data for demo purposes. As a one time process, I need to enable migrations first by running the "Enable-Migrations" command from the Package Manager Console.

Screenshot 2014-03-31 14.39.34

I will run the another command to add a migration code to reflect my context to a database schema: Add-Migration:

Screenshot 2014-03-31 14.41.44

Enable-Migration command created an internal class called Configuration and it contains a Seed method. I can use that seed method to inject some data during the database creation process:

protected override void Seed(SimpleOAuthSample.Models.OAuthDbContext context)
{
    context.Clients.AddOrUpdate(
        client => client.Name,
        new Client
        {
            Id = "42ff5dad3c274c97a3a7c3d44b67bb42",
            Name = "Demo Resource Owner Password Credentials Grant Client",
            ClientSecretHash = new PasswordHasher().HashPassword("client123456"),
            AllowedGrant = OAuthGrant.ResourceOwner,
            CreatedOn = DateTimeOffset.UtcNow
        });

    context.Users.AddOrUpdate(
        user => user.UserName,
        new IdentityUser("Tugberk")
        {
            Id = Guid.NewGuid().ToString("N"),
            PasswordHash = new PasswordHasher().HashPassword("user123456"),
            SecurityStamp = Guid.NewGuid().ToString(),
            Email = "tugberk@example.com",
            EmailConfirmed = true
        });
}

Now, I will use the Update-Database command to create my database:

Screenshot 2014-03-31 17.04.38

This command just created the database with the seed data on my SQL Express:

image

We will interact with our database mostly through the UserManager class which ASP.NET Identity core library provides. However, we will still use the OAuthDbContext directly. To use those classes efficiently, we need to write some setup code. I'll do this inside the OWIN Startup class:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.CreatePerOwinContext<OAuthDbContext>(() => new OAuthDbContext());
        app.CreatePerOwinContext<UserManager<IdentityUser>>(CreateManager);
    }

    private static UserManager<IdentityUser> CreateManager(
        IdentityFactoryOptions<UserManager<IdentityUser>> options,
        IOwinContext context)
    {
        var userStore =
            new UserStore<IdentityUser>(context.Get<OAuthDbContext>());

        var manager =
            new UserManager<IdentityUser>(userStore);

        return manager;
    }
}

This is the minimum code that we can write to use the UserManager class inside our OWIN components efficiently. Although I'm not fan of this approach, I chose to do it this way since doing it in my way would complicate the post.

OAuth Authorization Server Application with Katana OAuthAuthorizationServerMiddleware

Here we come to the real meat of the post. I will now set up the OAuth 2.0 token endpoint to support Resource Owner Password Credentials Grant by using the OAuthAuthorizationServerMiddleware which comes with the Microsoft.Owin.Security.OAuth library. There is a shorthand extension method on IAppBuilder to use this middleware: UseOAuthAuthorizationServer. I will use this extension method to configure my OAuth 2.0 endpoints through the Configuration method of my Startup class:

public void Configuration(IAppBuilder app)
{
    //... 
	
    app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    {
        TokenEndpointPath = new PathString("/oauth/token"),
        Provider = new MyOAuthAuthorizationServerProvider(),
        AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
#if DEBUG
        AllowInsecureHttp = true,
#endif
    });
}

I'm passing an instance of OAuthAuthorizationServerOptions here and setting a few of its properties. Everything is pretty much self explanatory except of Provider property. I'm setting an implementation of IOAuthAuthorizationServerProvider to Provider property to handle the request at the specific places. Fortunately, I didn't have to implement this interface from top to bottom as there is a default implementation of it (OAuthAuthorizationServerProvider) and I just needed to override the methods that I needed.

Spare some time to read the documentation of the OAuthAuthorizationServerProvider's methods. Those are pretty detailed and should give you a great head start.

public class MyOAuthAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task ValidateClientAuthentication(
        OAuthValidateClientAuthenticationContext context)
    {
        string clientId;
        string clientSecret;

        if (context.TryGetBasicCredentials(out clientId, out clientSecret))
        {
            UserManager<IdentityUser> userManager = 
                context.OwinContext.GetUserManager<UserManager<IdentityUser>>();
            OAuthDbContext dbContext = 
                context.OwinContext.Get<OAuthDbContext>();

            try
            {
                Client client = await dbContext
                    .Clients
                    .FirstOrDefaultAsync(clientEntity => clientEntity.Id == clientId);

                if (client != null &&
                    userManager.PasswordHasher.VerifyHashedPassword(
                        client.ClientSecretHash, clientSecret) == PasswordVerificationResult.Success)
                {
                    // Client has been verified.
                    context.OwinContext.Set<Client>("oauth:client", client);
                    context.Validated(clientId);
                }
                else
                {
                    // Client could not be validated.
                    context.SetError("invalid_client", "Client credentials are invalid.");
                    context.Rejected();
                }
            }
            catch
            {
                // Could not get the client through the IClientManager implementation.
                context.SetError("server_error");
                context.Rejected();
            }
        }
        else
        {
            // The client credentials could not be retrieved.
            context.SetError(
                "invalid_client", 
                "Client credentials could not be retrieved through the Authorization header.");

            context.Rejected();
        }
    }

    public override async Task GrantResourceOwnerCredentials(
        OAuthGrantResourceOwnerCredentialsContext context)
    {
        Client client = context.OwinContext.Get<Client>("oauth:client");
        if (client.AllowedGrant == OAuthGrant.ResourceOwner)
        {
            // Client flow matches the requested flow. Continue...
            UserManager<IdentityUser> userManager = 
                context.OwinContext.GetUserManager<UserManager<IdentityUser>>();

            IdentityUser user;
            try
            {
                user = await userManager.FindAsync(context.UserName, context.Password);
            }
            catch
            {
                // Could not retrieve the user.
                context.SetError("server_error");
                context.Rejected();

                // Return here so that we don't process further. Not ideal but needed to be done here.
                return;
            }

            if (user != null)
            {
                try
                {
                    // User is found. Signal this by calling context.Validated
                    ClaimsIdentity identity = await userManager.CreateIdentityAsync(
                        user, 
                        DefaultAuthenticationTypes.ExternalBearer);

                    context.Validated(identity);
                }
                catch
                {
                    // The ClaimsIdentity could not be created by the UserManager.
                    context.SetError("server_error");
                    context.Rejected();
                }
            }
            else
            {
                // The resource owner credentials are invalid or resource owner does not exist.
                context.SetError(
                    "access_denied", 
                    "The resource owner credentials are invalid or resource owner does not exist.");

                context.Rejected();
            }
        }
        else
        {
            // Client is not allowed for the 'Resource Owner Password Credentials Grant'.
            context.SetError(
                "invalid_grant", 
                "Client is not allowed for the 'Resource Owner Password Credentials Grant'");

            context.Rejected();
        }
    }
}

Petty much all the methods you will implement, you will be given a context class and you can signal the validity of the request at any point by calling the Validated and Rejected method with their provided signatures. I implemented two methods above (ValidateClientAuthentication and GrantResourceOwnerCredentials) and I performed Validated and Rejected at several points as I have seen it fit.

An HTTP POST request made to "/oauth/token" endpoint with response_type parameter set to "password" will first arrive at the ValidateClientAuthentication method. This is the place where you should retrieve the client credentials and validate it. According to OAuth 2.0 specification, the client credentials can also be sent as request parameters. However, I don't think this is such a good idea comparing to sending the credentials through basic authentication. That's why I only tried to get it from the "Authorization" header. If the client credentials are valid, the request will continue. If not, it will not process further and the error response will be returned as described inside the OAuth 2.0 specification.

If the client credentials are valid and the "response_type" parameter is set to password, the request will arrive at the GrantResourceOwnerCredentials method. Inside this method there are three things we will essentials do:

  • Validate the client's allowed grant. I's check if it's set to ResourceOwner.
  • If the client's grant type is valid, validate the resource owner credentials.
  • If resource owner credentials are valid, generate a claims identity for the resource owner and pass it to the Validated method.

If all goes as expected, the middleware will issue the access token.

Calling the OAuth Token Endpoint and Getting the Access Token

Let's try out the pieces that we have built. As you see previously, I have seeded a sample client and a sample user when during the database creation process. I will use those information to generate a valid OAuth 2.0 "Resource Owner Password Credentials Grant" request.

Request:

POST http://localhost:53523/oauth/token HTTP/1.1
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Authorization: Basic NDJmZjVkYWQzYzI3NGM5N2EzYTdjM2Q0NGI2N2JiNDI6Y2xpZW50MTIzNDU2
Host: localhost:53523
Content-Length: 56

grant_type=password&username=Tugberk&password=user123456

Response:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 550
Content-Type: application/json;charset=UTF-8
Expires: -1
Server: Microsoft-IIS/8.0
X-SourceFiles: =?UTF-8?B?RDpcRHJvcGJveFxBcHBzXFNhbXBsZXNcQXNwTmV0SWRlbnRpdHlTYW1wbGVzXFNpbXBsZU9BdXRoU2FtcGxlXFNpbXBsZU9BdXRoU2FtcGxlXG9hdXRoXHRva2Vu?=
X-Powered-By: ASP.NET
Date: Tue, 01 Apr 2014 13:56:32 GMT

{"access_token":"ydbP24rMOATt7TK3dBCjluD2F5LcLkoX8ud39X135x0a1LEvOgsPf0ekm4Lyu2a06Rv_Z105GRZT_NoclgTTf7Slt5_WNfe68zOUq22j6MqW4Fh__Abzjm6I8otDzxvCJpt5d73R-Um6GwTui3LDbcOk5bH2BZuQLTJsNLknbLPu_FdpgkYfBodUoyPiFhv5-gNBEsfp4gCZYfdKtlhaK0wtloZiIzH1_sNPhBt9FavSfThM5BeoWkz8PFxkv_cOsOhOIzK66nSx7B2XL7K9aLqPSJLxus2ud8GBZyteSeFi26L9oX9do7MyCL1nXa8D9DRWfcIXiQi1v19AwyhoupP3L-k89xOK6_NTSzYOVhSMG9Juz8VYHWGkJeYTmekmnVkCvQe7KMQ6PceeUFJnA88TkiHNhai0hV8j012OUxPpUN5zRPJOU81XywSkQ7oKE0UsX3hQamgFrXV9eA-TSwZd4Qr-P9w6a82OM66Te9E","token_type":"bearer","expires_in":1799}

We successfully retrieved the response and it contains the JSON response body which includes the access token in the format described inside the OAuth 2.0 specification.

Summary and What is Next

In this post, we have set up our authorization server and we have a working OAuth 2.0 token endpoint which only supports "Resource Owner Password Credentials Grant" for now. The code is available on GitHub if you are interested in. In the next post, we will create our web service and protect it using our authorization server. We will also see how we can call this web service successfully from a typical .NET application.

Resources

Tags