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.
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.
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 } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With