Estoy seguro de que esto es posible, pero no estoy seguro de cómo lograrlo. Tengo una implementación de OWIN OAUTH que actualmente acepta el nombre de usuario y la contraseña de los usuarios y los autentica en una base de datos. Me gustaría extender esto para pasar un Uid de SmartCard para admitir el inicio de sesión único con una SmartCard.
¿Puedo pasar parámetros adicionales en el inicio de sesión de OWIN y, de ser así, cómo? La premisa básica es que un usuario puede iniciar sesión con una combinación de nombre de usuario/contraseña o un uid de tarjeta inteligente (si pasa un uid de tarjeta inteligente y se encuentra en la base de datos, la aplicación iniciará la sesión del usuario)
Actualmente estoy pasando el nombre de username
, password
y el tipo de grant_type
y me gustaría agregar uid
a esa lista y recogerlo en mi AuthorizationServiceProvider
.
Puedo ver UserName
, Password
y ClientId
en OAuthGrantResourceOwnerCredentialsContext
pero no puedo ver ninguna otra propiedad que respalde lo que estoy tratando de lograr.
Esto es lo que tengo actualmente en mi proveedor de servicios
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); }
También quiero poder obtener Uid del contexto, pero no puedo ver cómo lograrlo, cualquier ayuda es muy apreciada.
Debe implementar ValidateClientAuthentication
si no lo ha hecho.
Este es el lugar donde debe validar a su cliente. En estos métodos, realizará algún tipo de validación de su cliente y establecerá los objetos/variable que se pueden leer en GrantResourceOwnerCredentials
.
Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
recibe un OAuthValidateClientAuthenticationContext
que contiene los campos adicionales que está pasando al publicar en su servidor de autorización.
En la imagen de arriba, he agregado un uid
de parámetro adicional en la cuarta posición.
Antes de validar su contexto:
context.Validated(clientId);
puede configurar su variable/objeto:
string uid = context.Parameters.Where(f => f.Key == "uid").Select(f => f.Value).SingleOrDefault()[0]; context.OwinContext.Set<string>("SmartCard", uid);
Ahora, en sus GrantResourceOwnerCredentials
, simplemente puede leer el valor y usarlo:
string uid = context.OwinContext.Get<string>("SmartCard");
Si desea obtener más información, puede echar un vistazo a este repositorio de github donde paso un objeto:
context.OwinContext.Set<ApplicationClient>("oauth:client", client);
Si descarga la solución completa, puede probarla con un cliente javascript/jquery.
ACTUALIZAR :
Pasaría un parámetro adicional (IE: uid ) en su solicitud HTTP POST:
Vainilla 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 } });