Introducing OAuth2 Code Flow and Refresh Token Support in Thinktecture IdentityServer

We recently merged OAuth2 code flow and refresh token support into the main branch on Github. Please give it a try and tell us if it is working for you or not. After that feedback phase I will release v2.2 (maybe in two weeks).

The OAuth2 client configuration page has two new options now: one for enabling code flow, and one for allowing refresh tokens for that client:

OAuth2 config

Remember you should always select only one flow type per client – rather create multiple clients for each flow you want to support (see my next post on OAuth2 vulnerabilities for more details).

Also note the tokens link at the bottom which brings you to the refresh token search page where you can (based on different search criteria) view and delete refresh tokens:

Refresh Token Search

We also changed the consent screen when refresh tokens are enabled for the client:

Consent with refresh token

From a code point of you, we use the (or rather a) standard OAuth2 query string syntax and you can use the OAuth2Client class from Thinktecture.IdentityModel as a convenience, e.g:

var url = OAuth2Client.CreateCodeFlowUrl(

    https://idsrv.local/issue/oauth2/authorize,

    “codeflowclient”,

    Constants.Scope,

    https://localhost:44303/callback);

Which results in the following URL:

https://idsrv.local/issue/oauth2/authorize?
  client_id=codeflowclient&
  scope=urn:webapisecurity&
  redirect_uri=https://localhost:44303/callback&
  response_type=code

After IdentityServer sends back the code – you can again use OAuth2Client to request the token:

var client = new OAuth2Client(
    new Uri("https://idsrv.local/issue/oauth2/token"),
    "codeflowclient",
    "secret");
var response = client.RequestAccessTokenCode(code);

 

If refresh tokens are enabled, you can request a fresh token like this:

var client = new OAuth2Client(
    new Uri("https://idsrv.local/issue/oauth2/token"),
    "codeflowclient",
    "secret");

var response = client.RequestAccessTokenRefreshToken(refreshToken);

 

The full sample can be found here.

This entry was posted in ASP.NET, IdentityModel, IdentityServer, OAuth, WebAPI. Bookmark the permalink.

17 Responses to Introducing OAuth2 Code Flow and Refresh Token Support in Thinktecture IdentityServer

  1. 2 questions.

    why not create provider class for plugging into the ASP.NET OAUTH(2) framework available to millions of visual studio programmers (rather than a custom client lib)? I’m not exactly smart, and I made 2 sets of callbacks : one for the OAUTH2 support in Azure ACS, and one for Ping Federate server’s new OAUTH features. The latter should easily evolve to interface to IDsrv.

    Why do both Ping Federate and IDsrv are enforcing one grant type per vendor-site registration? Mere committee dogma is not a good enough answer.

    In provider classes for Twitter or Live, one of courses uses the “graph API” endpoint ultimately to pull down the users attributes, as authorized by the graph service evaluating the accesstoken issued by a OAUTH2 handshake with the IDP’s authorization-granting and token-issuing endpoints. In PingFed (and ill guess IDSrv) the model seems unlike live/twitter/facebooks “graph” service – assume rather than the IDP will issue now a new type of access token – one bearing an attribute statement. One will talk to this STS using a “custom” grant type that induces the token-issuing endpoint to swap an opaque token for an access token now with embedded attribute statement, in some or other blob format. To be honest, I prefer the fourth-party graph API, approach (e.g. Azure AD’s model) to all this dogmatic design about IDPs. The IDP approach just makes OAUTH look like SAML/ws-fedp, now with new syntaxes.

  2. OAuth2 is about authorization – why do you want to do authentication with it?

  3. brockallen says:

    “Why do both Ping Federate and IDsrv are enforcing one grant type per vendor-site registration? Mere committee dogma is not a good enough answer.”

    Do you mean scope when you say grant type?

  4. Ion Singh says:

    Hi Dominick.

    I see your point – I take that back. I just thought it may easier to provide an ASP.NET IAuthenticationClient the plugs in nicely with IDsrv ;) I realise now that the facebook and ms are using oauth2 and google and yahoo are using openid. You are right that it has nothing to do with oauth2 directly, just in a sort of round about way.

    How would I secure an asp mvc webapi app using the following /api/values?access_token={RequestAccessTokenCode}. This is a separate standalone web app do O need to call IDsrv back in my api controller to validate the token in a ActionFilterAttribute. Or is something available?

  5. No need to call back – request the access token via the appropriate flow. Then send it to the API (if you really want a query string…header would be preferred). Validate the token in the API.

  6. Ion Singh says:

    Is there a helper class I can call to validate.

    I wrote some custom code.

    string query = Request.RequestUri.Query;
    string accessToken = HttpUtility.ParseQueryString(query).Get(“access_token”);
    var handler = FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers[“urn:ietf:params:oauth:token-type:jwt”];
    var token = handler.ReadToken(accessToken);
    Not sure how validate???

  7. Ion Singh says:

    Ok, i was able to find: var identity = handler.ValidateToken(token);

    My question is there an http handler available to do this in Thinktecture.IdentityModel, or is something custom I have to write?

  8. Ion Singh says:

    Finally figured it out.. Thanks for you hard-work on this… I guess in the end I needed to figure it for myself.
    var authentication = new AuthenticationConfiguration
    {
    ClaimsAuthenticationManager = new MySimpleClaimsTransformerThatDoesNothing(),
    RequireSsl = false,
    EnableSessionToken = true,
    DefaultAuthenticationScheme =”JWT”
    };

    authentication.AddJsonWebToken(
    issuer: “http://identityserver.v2.thinktecture.com/trust/yo”,
    audience: “urn:yo.basic”,
    signingKey: “324uzQ1usdfsdfsWsxehA234f=”,
    options: AuthenticationOptions.ForQueryString(“access_token”));

    I did end up creating a OAuthWebSecurity.RegisterIdSrvClient() to simplify the process.

  9. Cool! (and sorry for the delays – easter holidays here)

  10. Hi there,

    I would really like to try the Auth Code Flow but I am not able to find V2.2 branch on GitHub.
    Can you help me with this? Am I to stupid to find it?

    @Dominick
    Will you implememt the recently released official MS version of the Jwt token (System.Identity… 1.0.0). Maybe you can tell when you think it will be finished and implemented into TT Id Server.

    Lastbutnotleast: Thanks a lot for all your knowledge you are sharing with us and of course your nice framework and STS.

    Cheers,
    Gordon

  11. Joe says:

    Hi! I’ve been getting an invalid_scope error when trying to use a Php client to connect, and having it provide the scope used here: urn:webapisecurity
    I’ve done everything else as suggested above. Any thoughts on what the scope should be? I also tried sending the scope “identity” which is used in the sample php program. The RFC says the choice of scopes is at the discretion of identity server. What scopes are proper for OAuth2 Authorization Code Grant? Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s