Estoy tratando de configurar mi autenticación mediante el authorization_code flujo de subvenciones. Yo había trabajado anteriormente con grant_type=password, así que tipo de saber cómo las cosas se supone que funciona. Pero cuando se utiliza grant_type=authorization_code, no podía hacerla volver otra cosa que invalid_grant

Aquí es mi configuración:

app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
    AllowInsecureHttp = true,
    TokenEndpointPath = new PathString("/auth/token"),
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),
    Provider = new SampleAuthProvider()
});

app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions
{
    AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
    AuthenticationType = "Bearer"
});

SampleAuthProvider es el siguiente: clase de https://gist.github.com/anonymous/8a0079b705423b406c00

Básicamente, es sólo el registro de cada paso y validando el mismo. He probado la solicitud:

POST http://localhost:12345/auth/token
grant_type=authorization_code&code=xxxxxx&client_id=xxxxx&redirect_uri=https://xxxx.com/
Content-Type: application/x-www-form-urlencoded

Va a través de:

  • OnMatchEndpoint
  • OnValidateClientAuthentication

Y eso es todo. Yo esperaba que la llamada OnValidateTokenRequest y OnGrantAuthorizationCodesiguiente, pero no hicieron nada. No tengo idea de por qué.

La xxxx‘s en la petición no son marcadores de posición, lo he probado así. Tal vez el middleware hace algunos controles sobre su propia y rechaza la solicitud debido a que? Traté de variantes de la redirect_uri con http, sin ningún tipo de protocolo, sin barra diagonal…

También funciona correctamente con una costumbre grant_type. Es así que si estoy demasiado desesperado, supongo que se puede utilizar para simular authorization_code, pero yo prefiero no tener que hacer eso.

TL;DR

Mi OAuthAuthorizationServerProvider devuelve {"error":"invalid_grant"}después de OnValidateClientAuthentication cuando se utiliza grant_type=authorization_code.

  • ¿Por qué es parar allí?
  • ¿Cómo puedo hacer que todo el maldito trabajo?

Gracias por su ayuda!


Editar

Como se ha señalado por RajeshKannan, he cometido un error en la configuración de mi. Yo no proporcionar una AuthorizationCodeProvider instancia. Sin embargo, no resuelve completamente el problema, ya que en mi caso, el código no está emitido por la AuthorizationCodeProvider, y yo simplemente no puede deserializar ella. Yo anwered con la solución que me puse a trabajar.

InformationsquelleAutor dgn | 2014-07-01

4 Comentarios

  1. 10

    Aquí es lo que me puse a trabajar. No estoy completamente cómodo con la solución, pero funciona y debería ayudar a los demás a solucionar sus problemas.


    Así, el problema es que yo no tenía la AuthorizationCodeProvider de la propiedad. Cuando una solicitud con grant_type=authorization_code es recibido, el código debe ser validado por código de proveedor. El marco se supone que el código fue expedido por que el código de proveedor, pero ese no es mi caso. Lo tengo desde otro servidor y tiene que enviar el código para validación.

    En el caso estándar, en el que también están el uno expide el código, el enlace proporcionado por RajeshKannan describe todo lo que tiene que hacer.

    Aquí es donde usted tiene que establecer la propiedad:

    app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    {
        TokenEndpointPath = new PathString(Paths.TokenPath),
        Provider = new SampleAuthProvider(),
        AuthorizationCodeProvider = new MyAuthorizationCodeProvider ()
    }

    Y la declaración de la MyAuthorizationCodeProvider clase:

    internal class MyAuthorizationCodeProvider : AuthenticationTokenProvider
    {
        public override async Task ReceiveAsync(
            AuthenticationTokenReceiveContext context)
        {
            object form;
            //Definitely doesn't feel right
            context.OwinContext.Environment.TryGetValue(
                    "Microsoft.Owin.Form#collection", out form); 
            var redirectUris = (form as FormCollection).GetValues("redirect_uri");
            var clientIds = (form as FormCollection).GetValues("client_id");
            if (redirectUris != null && clientIds != null)
            {
                //Queries the external server to validate the token
                string username = await MySsoService.GetUserName(context.Token,
                                                                 redirectUris[0]);
                if (!string.IsNullOrEmpty(username))
                {
                    var identity = new ClaimsIdentity(new List<Claim>()
                    {
                        //I need the username in  GrantAuthorizationCode
                        new Claim(ClaimTypes.NameIdentifier, username) 
                    }, DefaultAuthenticationTypes.ExternalBearer);
    
                    var authProps = new AuthenticationProperties();
    
                    //Required. The request is rejected if it's not provided
                    authProps.Dictionary.Add("client_id", clientIds[0]); 
    
                    //Required, must be in the future
                    authProps.ExpiresUtc = DateTimeOffset.Now.AddMinutes(1); 
    
                    var ticket = new AuthenticationTicket(identity, authProps);
                    context.SetTicket(ticket);
                }
            }
        }
    }
    • Hola @escenario, ¿te las arreglas para encontrar un camino mejor? Yo estoy con el mismo problema
    • Lo siento, dejé de trabajar en ese proyecto, así que no tengo más actualizaciones sobre el tema. Que solución funcionó bien. La API está diseñada sólo con otros casos de uso en mente. Tal vez en futuras actualizaciones que será factible sin codificado de llaves, moldes y co.
  2. 3

    Tuve el mismo error. Las cosas que me estaba perdiendo:

    • Especificar OAuthAuthorizationServerOptions.AuthorizationCodeProvider de acuerdo a la documentación.
    • Especificar el mismo client_id como un parámetro cuando se hace una solicitud para el token extremo como lo hizo cuando recibió la authorization_code.
    • Reemplazar OAuthAuthorizationServerProvider.ValidateClientAuthentication y en la llamada a este método context.TryGetFormCredentials. Este establece la propiedad context.ClientId para el valor de la client_id OBTENER parámetros. Esta propiedad se debe establecer, de lo contrario obtendrá el invalid_grant de error. También, llame context.Validated().

    Después de hacer todo lo anterior, finalmente pude intercambiar la authorization_code a un access_token en el token extremo.

  3. 1

    Asegúrese de que ha configurado su servidor de autorización de opciones.
    Creo que usted debe proporcionar su autorizar el punto final de detalles:

     AuthorizeEndpointPath = new PathString(Paths.AuthorizePath)

    En el link de abajo, el código de autorización de la subvención será explicada en detalle y se muestra el método que estuvieron involucrados en el código de autorización de concesión de ciclo de vida.

    Owin servidor de autorización de Oauth

    • Gracias tu respuesta me puso en el camino correcto. He editado la pregunta a explicar lo que he tenido que cambiar. Pero se siente raro. Me estoy perdiendo de una manera más fácil para obtener los parámetros de la consulta y pasarlos al Proveedor? O tal vez yo no debería entrar en contacto con mi Servidor de SSO como que?
  4. 1

    Gracias escenario, Mi código era faltan los siguientes dos valores requeridos. Publicado aquí en el caso de que otros la encuentren útil:

                //Required. The request is rejected if it's not provided
                authProps.Dictionary.Add("client_id", clientIds[0]); 
    
                //Required, must be in the future
                authProps.ExpiresUtc = DateTimeOffset.Now.AddMinutes(1); 

Dejar respuesta

Please enter your comment!
Please enter your name here