AuthorizationCodeProvider

AuthorizationCodeProvider

我正在尝试使用authorization_code授予流程来设置我的身份验证。我以前使用过grant_type=password,所以我有点知道这些东西应该如何工作。但是当使用grant_type=authorization_code时,我无法使其返回除invalid_grant之外的任何内容

这是我的设置:

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是以下类:https://gist.github.com/anonymous/8a0079b705423b406c00

基本上,它只是记录每个步骤并进行验证。我尝试了该请求:
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

它正在经历:
  • OnMatchEndpoint
  • OnValidateClientAuthentication

  • 就这样。我希望它接下来可以调用OnValidateTokenRequestOnGrantAuthorizationCode,但事实并非如此。我不知道为什么。

    请求中的xxxx不是占位符,我这样尝试过。也许中间件自己进行一些检查并因此拒绝请求?我尝试了redirect_urihttp的变体,没有任何协议(protocol),没有结尾的斜杠...

    它也可以与自定义grant_type一起正常工作。因此,如果我太绝望了,我想我可以用它来模拟authorization_code,但是我宁愿不必那样做。

    TL; DR

    使用OAuthAuthorizationServerProvider时,我的{"error":"invalid_grant"}OnValidateClientAuthentication之后返回grant_type=authorization_code
  • 为什么停在那里?
  • 如何使整个该死的事情起作用?

  • 谢谢你的帮助!

    编辑

    正如RajeshKannan指出的那样,我在配置中犯了一个错误。我没有提供AuthorizationCodeProvider实例。但是,这并不能完全解决问题,因为在我的情况下,该代码不是由AuthorizationCodeProvider发出的,我不能反序列化它。我忙于解决方法。

    最佳答案

    这就是我的工作。我对该解决方案并不完全满意,但是它可以正常工作,并且应该帮助其他人解决他们的问题。

    因此,问题在于我没有设置AuthorizationCodeProvider属性。收到带有grant_type=authorization_code的请求时,该代码提供者必须验证该代码。该框架假定该代码是由该代码提供者发出的,但这不是我的情况。我是从另一台服务器上获得的,必须将代码发送回去进行验证。

    在标准情况下,您也是发出代码的人,RajeshKannan提供的链接描述了您必须执行的所有操作。

    这是您必须设置属性的地方:

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

    以及MyAuthorizationCodeProvider类的声明:
    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);
                }
            }
        }
    }
    

    10-08 12:35