Asp.net

Owin.Security.OAuth 上的 Authorization_code 授權流程:返回 invalid_grant

  • September 9, 2021

我正在嘗試使用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_uri我嘗試了with的變體http,沒有任何協議,沒有斜杠……

它也適用於自定義grant_type. 所以如果我太絕望了,我想我可以用它來模擬authorization_code,但我寧願不必那樣做。

TL; 博士

我使用後的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);
           }
       }
   }
}

引用自:https://stackoverflow.com/questions/24515211