Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you consume extra parameters in OAuth2 Token request within .net WebApi2 application

I have an api specific project in a large .net MVC 5 web solution. I am utilizing the WebApi2 templates out of the box to authenticate a user through the api. Using individual accounts to authenticate, the request body required to get an access token is:

grant_type=password&username={someuser}&password={somepassword} 

This works as expected.

However, I need to add a 3rd dimension to the scaffolded method "GrantResourceOwnerCredentials". In addition to checking the username/password, i need to add a device id, which is meant to restrict access from a user account to a specific device. What's not clear is how to add these extra request parameters to the already defined "OAuthGrantResourceOwnerCredentialsContext". This context currently makes room for UserName and Password, but obviously i'll need to include more.

My question is simply, is there a standard way to extend the login requirements for the OWIN OAuth2 token request to include more data? And, how would you reliably do that in a .NET WebApi2 environment?

like image 727
nak5ive Avatar asked Jan 20 '14 20:01

nak5ive


People also ask

How does OAuth2 token work?

It works by delegating user authentication to the service that hosts a user account and authorizing third-party applications to access that user account. OAuth 2 provides authorization flows for web and desktop applications, as well as mobile devices.

What does an OAuth2 token contain?

Principles of OAuth2. As such, it is designed primarily as a means of granting access to a set of resources, for example, remote APIs or user's data. OAuth 2.0 uses Access Tokens. An Access Token is a piece of data that represents the authorization to access resources on behalf of the end-user.


1 Answers

As it often is the case, I found the answer immediately after submitting the question...

ApplicationOAuthProvider.cs contains the following code out-of-the-box

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) {     using (UserManager<IdentityUser> userManager = _userManagerFactory())     {         IdentityUser user = await userManager.FindAsync(context.UserName, context.Password);          if (user == null)         {             context.SetError("invalid_grant", "The user name or password is incorrect.");             return;         }          ClaimsIdentity oAuthIdentity = await userManager.CreateIdentityAsync(user,             context.Options.AuthenticationType);         ClaimsIdentity cookiesIdentity = await userManager.CreateIdentityAsync(user,             CookieAuthenticationDefaults.AuthenticationType);         AuthenticationProperties properties = CreateProperties(context.UserName, data["udid"]);         AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);         context.Validated(ticket);         context.Request.Context.Authentication.SignIn(cookiesIdentity);     } } 

By simply adding

var data = await context.Request.ReadFormAsync(); 

within the method, you can access all posted variables in the request body and use them as you like. In my case, I placed it immediately after the null-check on the user to perform a more restrictive security check.

Hope this helps someone!

like image 72
nak5ive Avatar answered Sep 23 '22 17:09

nak5ive