ASP.Net Identity 2: respuesta personalizada de OAuthAuthorizationServerProvider
Esta pregunta es la continuación de mi anterior:Inicio de sesión de ASP.Net Identity 2 con contraseña de SMS, sin autenticación de dos factores
He creado mi OAuthAuthorizationServerProvider personalizado para admitir el tipo de concesión personalizado.
Mi idea era crear grant_type desms
eso permitirá al usuario generar un código de acceso único que se enviará a su teléfono móvil y luego el usuario como contraseña cuando envíe una solicitud con grant_type de contraseña.
Ahora, después de generar, almacenar y enviar por SMS esa contraseña, me gustaría devolver una respuesta personalizada, no un token de mi GrantCustomExtension.
public override async Task GrantCustomExtension(OAuthGrantCustomExtensionContext context)
{
const string allowedOrigin = "*";
context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] {allowedOrigin});
if (context.GrantType != "sms")
{
context.SetError("invalid_grant", "unsupported grant_type");
return;
}
var userName = context.Parameters.Get("username");
if (userName == null)
{
context.SetError("invalid_grant", "username is required");
return;
}
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
ApplicationUser user = await userManager.FindByNameAsync(userName);
if (user == null)
{
context.SetError("invalid_grant", "user not found");
return;
}
var generator = new TotpSecurityStampBasedTokenProvider<ApplicationUser, string>();
await userManager.UpdateSecurityStampAsync(user.Id);
var accessCode = await generator.GenerateAsync("SMS", userManager, user);
var accessCodeExpirationTime = TimeSpan.FromMinutes(5);
var result = await userManager.AddAccessCode(user, accessCode, accessCodeExpirationTime);
if(result.Succeeded)
{
Debug.WriteLine("Login code:"+accessCode);
//here I'll send login code to user phone via SMS
}
//return 200 (OK)
//with content type="application/json; charset=utf-8"
//and custom json content {"message":"code send","expires_in":300}
//skip part below
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "SMS");
var ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);
}
¿Cómo puedo dejar de generar token y devolver una respuesta personalizada de OAuthAuthorizationServerProvider?
Soy consciente de dos métodos:TokenEndpoint
, TokenEndpointResponse
, pero me gustaría anular toda la respuesta, no solo el token.
EDITAR:
Por ahora estoy creando ClaimsIdentity temporal enGrantCustomExtension
usando el código a continuación:
var ci = new ClaimsIdentity();
ci.AddClaim(new Claim("message","send"));
ci.AddClaim(new Claim("expires_in", accessCodeExpirationTime.TotalSeconds.ToString(CultureInfo.InvariantCulture)));
context.Validated(ci);
y estoy anulandoTokenEndpointResponse
:
public override Task TokenEndpointResponse(OAuthTokenEndpointResponseContext context)
{
if (context.TokenEndpointRequest.GrantType != "sms") return base.TokenEndpointResponse(context);
//clear response containing temporary token.
HttpContext.Current.Response.SuppressContent = true;
return Task.FromResult<object>(null);
}
Esto tiene dos problemas: al llamarcontext.Validated(ci);
Estoy diciendo que este es un usuario válido, pero en cambio me gustaría responder información que he enviado el código de acceso por SMS.HttpContext.Current.Response.SuppressContent = true;
borra la respuesta, pero me gustaría devolver algo en lugar de una respuesta vacía.