ThinktectureのIdentityServer 3をセットアップしようとしていますが、認証コードを交換するとき(またはResourceOwnerフローを使用するとき)に更新トークンを返すように見えませんが、認証コードに焦点を当てます。今の私にとってもっと重要なので)。アクセストークンを取得し、それらを使用して正常に認証できますが、取得する予定の更新トークンが生成されていないようです。 Identity Serverに更新トークンを返すために必要な特別なことはありますか?
私はドキュメントを調べましたが、間違って設定したものは何も見ていません。 refresh tokens のページで、私が行っていないのは明示的に「認証のためにユーザーをそこに送信するときのoffline_access」スコープ。試行するたびに「invalidscope」エラーが発生するためです。したがって、Thinktectureの「offline_accessスコープを(コードまたはリソース所有者フローを介して)要求する」という表現は、offline_accessスコープが使用しているフローに基づいて自動的に要求されるものであることを意味します。
私は彼らのサンプルアプリケーション(そして Katana Project からの既存のOwinミドルウェアのソースコード)にできる限り従おうとしています。私のセットアップは次のとおりです。
var client = new Client() { ClientId = "SomeId"、 ClientName = "Client with Authentication Code Flow"、 RequireConsent = false、//これをtrueに設定しても役に立ちませんでした Flow = Flows.AuthorizationCode、 ClientSecrets = new List(){ new ClientSecret( "secret") }、 RedirectUris = new List() { "localhost:/ specific-redirect-path" } };
var authenticationEndpoint = AuthorizationEndpointBase + "?client_id =" + Uri.EscapeDataString(Options.ClientId)+ "&scope = Default" + "&response_type = code" + "&redirect_uri =" + Uri.EscapeDataString(redirectUri)+ "&state =" + Uri.EscapeDataString(state); Response.Redirect( authenticationEndpoint);ここで、「デフォルト」は私が作成したスコープです。
IReadableStringCollection query = Request.Query; string code = getValueFromQueryString( "code"、query); var tokenRequestParameters = new List>() { new KeyValuePair( "client_id"、Options.ClientId)、 new KeyValuePair( "redirect_uri"、GenerateRedirectUri())、 new KeyValuePair( "client_secret"、Options.ClientSecret)、 new KeyValuePair( "code"、code)、 new KeyValuePair( "grant_type"、 "authorization_code")、 }; var requestContent = new FormUrlEncodedContent(tokenRequestParameters ); HttpResponseMessage response = await _httpClient.PostAsync(TokenEndpoint、requestContent、Request.CallCancelled); response.EnsureSuccessStatusCode(); string oauthTokenResponse = await response.Content.ReadAsStringAsync( );
トークンエンドポイントを呼び出すと、Identity Serverにログオンすると次のように表示されます(認証コードの検証後)。
iisexpress.exe情報:0:[Thinktecture.IdentityServer.Core.Validation.TokenRequestValidator]:2015年7月13日1:44:07 PM +00:00-トークンリクエストの検証に成功しました { "ClientId": "SomeId"、 "ClientName": "認証コードフローを持つクライアント"、 "GrantType": "authorization_code"、 "AuthorizationCode": "f8f795e649044067ebd96a341c5af8c3" } iisexpress.exe情報:0:[Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]:2015年7月13日1:44:07 PM +00:00-トークン応答の作成 iisexpress.exe情報:0:[Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]:2015年7月13日1: 44:07 PM +00:00-認証コードリクエストの処理 デバッグ:[Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]:2015年7月13日1 :44:07 PM +00:00-アクセストークンの作成 デバッグ:[Thinktecture.IdentityServer。 Core.Services.Default.DefaultTokenService]:2015年7月13日1:44:07 PM +00:00-参照アクセストークンの作成 iisexpress.exe情報:0 :[Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]:2015年7月13日1:44:07 PM + 00:00-トークンリクエストの終了 iisexpress.exe情報:0:[Thinktecture.IdentityServer.Core.Results.TokenResult]:2015年7月13日1:44:07 PM +00:00-トークン応答を返します。
他に何が適切かわからないので、必要に応じてさらに情報を提供します。
リクエストで「offline_access」を明示的に要求する必要があります。要求している他のスコープはスペースで区切ります。 (以下の例では、アプリで定義されたスコープについて話していることを明確にするために、「Default」を「MyApi」に置き換えています。)
&scope=MyApi offline_access
ただし、そのクライアントに更新トークンを取得する権利も付与する必要があります。これは、選択したフローに基づいて行われるだけではありません。
var client = new Client()
{
... //All the stuff you were doing before
ScopeRestrictions = new List<string>
{
"MyApi",
StandardScopes.OfflineAccess.Name, //"offline_access" -for refresh tokens
//Other commonly requested scopes:
//StandardScopes.OpenId.Name, //"openid"
//StandardScopes.Email.Name, //"email"
},
}
スコープストアにも「offline_access」を追加する必要がある場合があります。スコープストアは、IdentityServerが認識しているスコープのリストです。あなたの質問は、スコープストアがプロジェクトでどのように設定されているかについて言及していないので、すでに持っている可能性があります。ただし、上記がすぐに機能しない場合は、作業元の例でこのようなコードを探して、OfflineAccessを追加することをお勧めします。
var scopeStore = new InMemoryScopeStore(new Scope[]{
StandardScopes.OpenId,
StandardScopes.Profile,
StandardScopes.Email,
StandardScopes.OfflineAccess, //<--- ensure this is here to allow refresh tokens
new Scope{
Enabled = true,
Name = "MyApi"
},
}
トークンリクエストの送信中にスコープにoffline_access値を追加します
new Client
{
ClientId = "ro.angular",
AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.Address,
"api1",
IdentityServerConstants.StandardScopes.OfflineAccess
},
AllowOfflineAccess = true,
RefreshTokenUsage = TokenUsage.ReUse,
RefreshTokenExpiration = TokenExpiration.Sliding
}