I'm trying to set up Thinktecture's Identity Server 3, but I can't seem to get it to return a refresh token when exchanging an authorization code (or when using the ResourceOwner flow, but I'm going to focus on the authorization code as it's more important to me right now). I get back access tokens and can use them to authenticate just fine, but it doesn't seem to even be generating the refresh tokens that I'm expecting to get back. Is there anything special that I need to do to get Identity Server to return refresh tokens?
I've looked through the documentation, but haven't seen anything that I've set up wrong, and the only thing on their page on refresh tokens that I'm not doing is explicitly requesting the "offline_access" scope when sending the user there for authentication, because whenever I try I get an "invalid scope" error. Therefore, I'm taking Thinktecture's phrasing of "Request the offline_access scope (via code or resource owner flow)" to mean that the offline_access scope is something automatically requested based on the flow you're using.
I've been trying to follow their sample applications (And the source code for the existing Owin Middleware from the Katana Project) as best I can, and my setup is as follows:
- I've created a client using their client class, manually specifying the following:
var client = new Client() { ClientId = "SomeId", ClientName = "Client with Authentication Code Flow", RequireConsent = false, //Setting this to true didn't help Flow = Flows.AuthorizationCode, ClientSecrets = new List() { new ClientSecret("secret") }, RedirectUris = new List() { "localhost:/specific-redirect-path" } };
- I'm making a call to the Authorization endpoint as follows:
var authorizationEndpoint = AuthorizationEndpointBase + "?client_id=" + Uri.EscapeDataString(Options.ClientId) + "&scope=Default" + "&response_type=code" + "&redirect_uri=" + Uri.EscapeDataString(redirectUri) + "&state=" + Uri.EscapeDataString(state); Response.Redirect(authorizationEndpoint);
where "Default" is a scope I created. - In my callback, I call the token endpoint as follows:
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();
When I make the call to the token endpoint, my logging on Identity Server displays the following (after the validation of the authorization code):
iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Validation.TokenRequestValidator]: 7/13/2015 1:44:07 PM +00:00 -- Token request validation success { "ClientId": "SomeId", "ClientName": "Client with Authentication Code Flow", "GrantType": "authorization_code", "AuthorizationCode": "f8f795e649044067ebd96a341c5af8c3" } iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Creating token response iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.ResponseHandling.TokenResponseGenerator]: 7/13/2015 1:44:07 PM +00:00 -- Processing authorization code request Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating access token Debug: [Thinktecture.IdentityServer.Core.Services.Default.DefaultTokenService]: 7/13/2015 1:44:07 PM +00:00 -- Creating reference access token iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Endpoints.TokenEndpointController]: 7/13/2015 1:44:07 PM +00:00 -- End token request iisexpress.exe Information: 0 : [Thinktecture.IdentityServer.Core.Results.TokenResult]: 7/13/2015 1:44:07 PM +00:00 -- Returning token response.
I'm not sure what else would be pertinent, so I'll provide more information as needed.