Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

owin oauth send additional parameters

I'm sure this is possible but not certain how to achieve. I have an OWIN OAUTH implementation that currently accepts the users Username and Password and authenticates them against a database. I would like to extend this to pass in a SmartCard Uid to support single sign-on with a SmartCard.

Can I pass in additional parameters in the OWIN login and if so how? The basic premise is that a user can login with a username/password combination Or a SmartCard uid (if passing a SmartCard uid and that is found in the database then the application will log the user in)

I am currently passing in username, password and grant_type and I would like to add uid to that list and pick that up in the my AuthorizationServiceProvider.

I can see UserName, Password and ClientId on the OAuthGrantResourceOwnerCredentialsContext but I cannot see any other properties that would support what I am trying to achieve.

This is what I currently have in my service provider

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)     {         context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });          var user = await this._userService.FindUser(context.UserName, context.Password);          if (user == null)         {             context.SetError("invalid_grant", "The user name or password is incorrect.");             return;         }          var identity = new ClaimsIdentity(context.Options.AuthenticationType);         identity.AddClaim(new Claim(ClaimTypes.Sid, user.Id.ToString()));         identity.AddClaim(new Claim(ClaimTypes.Role, "user"));         identity.AddClaim(new Claim("sub", context.UserName));          var secretKeyBytes = Encoding.UTF8.GetBytes(user.PasswordHash);         var props =             new AuthenticationProperties(                 new Dictionary<string, string>                     {                         { "dm:appid", user.Id.ToString() },                         { "dm:apikey", Convert.ToBase64String(secretKeyBytes) }                     });          var ticket = new AuthenticationTicket(identity, props);         context.Validated(ticket);     } 

I want to be able to get Uid from the context as well but cannot see anyway of achieving this, any help is greatly appreciated.

like image 932
Neil Stevens Avatar asked Jul 15 '15 22:07

Neil Stevens


1 Answers

You have to implement ValidateClientAuthentication if you haven't done so.

This is the place where you should validate your client. In this methods you will do some sort of validation of your client and set the objects/variable which can be read in GrantResourceOwnerCredentials.

Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) 

receives an OAuthValidateClientAuthenticationContext which contains the additional field(s) you're passing when POSTing to your authorization server.

enter image description here

In the picture above I've added an extra parameter uid in 4th position.

Before you validate your context:

context.Validated(clientId); 

you can set your variable/object:

string uid = context.Parameters.Where(f => f.Key == "uid").Select(f => f.Value).SingleOrDefault()[0]; context.OwinContext.Set<string>("SmartCard", uid); 

Now, in your GrantResourceOwnerCredentials you can simply read the value and use it:

string uid = context.OwinContext.Get<string>("SmartCard"); 

If you want to find out more you can have a look at this github repository where I pass an object:

context.OwinContext.Set<ApplicationClient>("oauth:client", client); 

If you download the whole solution you can test it with a javascript/jquery client.

UPDATE:

You would pass an additional parameter (IE: uid) in your http POST request:

Vanilla Js:

var request = new XMLHttpRequest(); request.open('POST', oAuth.AuthorizationServer, true); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); request.setRequestHeader('Authorization', 'Basic ' + authorizationBasic); request.setRequestHeader('Accept', 'application/json'); request.send("username=John&password=Smith&grant_type=password&uid=b17ac911-4cf1-4a3e-84a9-beac7b9da157"); 

jQuery:

$.ajax({         type: 'POST',         url: oAuth.AuthorizationServer,         data: { username: 'John', password: 'Smith', grant_type: 'password', uid: 'b17ac911-4cf1-4a3e-84a9-beac7b9da157' },         dataType: "json",         contentType: 'application/x-www-form-urlencoded; charset=utf-8',         xhrFields: {         withCredentials: true     },         // crossDomain: true,         headers: {                 'Authorization': 'Basic ' + authorizationBasic     } }); 
like image 116
LeftyX Avatar answered Sep 20 '22 03:09

LeftyX