Identity Server: From Implicit to Hybrid Flow

This post is a continuation of a series of posts that follow my initial looking into using IdentityServer4 in ASP.NET Core with an API and an Angular front end. The following are the related posts.

Identity Server: Introduction
Identity Server: Sample Exploration and Initial Project Setup
Identity Server: Interactive Login using MVC
Identity Server: From Implicit to Hybrid Flow (this post)
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angularsing MVC

This post is going to cover adding back in the API access that was lost in the last post by changing the MVC client to use a hybrid grant instead of an implicit grant. This post was written while working through Switching to Hybrid Flow and adding API Access back in the official docs.

Identity Application

The changes to the Identity Application are pretty simple and only involve tweaking the settings on the MVC client found in the  GetClients function of the  Config class. First, change the  AllowedGrantTypes from  Implicit to  HybridAndClientCredentials. Next, a client secret should be added.

This is, of course, a bad secret, but this is only an example. Next, add  "apiApp" to the  AllowedScopes and finally add  AllowOfflineAccess = true. The following is the full client code.

Most of the above are straight forward.  AllowedGrantTypes is what is moving to the hybrid flow which then needs a client secret to ensure everything is on the up and up. This client should be able to hit the API application so it is added to the allowed scopes.  AllowOfflineAccess is less clear to me. According to the docs, it allows the requesting refresh tokens for long-lived API access. This would take some more digging before production to ensure authorization isn’t too long lived.

Client Application

Changes to the client application were pretty minimal as well. First, in the  Configure function of the  Startup class, the  UseOpenIdConnectAuthentication call must pass a few more items. The following is the full set up.

ClientSecret should match what was set up for the client in the Identity Application. According to the docs setting  ResponseType to  code id_token means use a hybrid flow. This is another point that I would want to dig more on.  Scope is requesting access to the API Application and offline access which is the matching part to the offline access set up in the Identity Application.  GetClaimsFromUserInfoEndpoint tells the middleware to go to the user info endpoint to retrieve additional claims after getting an identity token.

Identity Controller

The  Index action in the  IdentityController ends up being much simpler than it was in the previous posts. The following is the full function.

In the new version, the token can be retrieved from the HTTP context instead of using the  DiscoveryClient and  TokenClient like the previous version of this code did. The general idea is the same in both which is to get a token, use the token as part of a request to the API application, and finally display the response in a view.

Identity View

The last set of changes is to the  Index.cshtml file in the View/Identity directory which is the view that goes with the Index action of the  IdentityController. The view displays the access token, refresh token, results of the API call, and the logged in user’s claims.

Wrapping up

Adding back API access was pretty easy and the new setup will make managing other resources pretty simple. The identity space is still pretty new to me but working through the IdentityServer quickstarts are helping get me up to a basic level of knowledge. The finished code for this post can be found here. Come back next week to convert this example to use ASP.NET Core Identity.

4 thoughts on “Identity Server: From Implicit to Hybrid Flow”

  1. Thanks for the article!

    I’m kinda new with the IdentityServer4 I have a question regarding the Client Application startup.cs->Configure->
    app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
    AuthenticationScheme = “oidc”,
    SignInScheme = “Cookies”,
    Authority = “http://localhost:5000”,
    RequireHttpsMetadata = false,

    ClientId = “mvc”,
    ClientSecret = “secret”,

    ResponseType = “code id_token”,
    Scope = { “apiApp”, “offline_access” },

    GetClaimsFromUserInfoEndpoint = true,
    SaveTokens = true

    For the past few days I always saw example like this here you are setting up the ClientId and the ClientSecret so the way it goes is this will be hardcoded value, how do you do it in a real world application? I’m building right now an application with similar approach and I’m using the Client Model/Class for IdentityServer which will act as the actual client for my app with that the case then it means that my ClientId and ClientSecret will be store in the database but not hardcoded, I hope you can elaborate more and help me on this one? or maybe other that has the same question

    Than you in Advance and again great article! will look into the other.

    1. Eds one option is to store this type of information in a database. If you check out this post it covers doing this with Entity Framework.

      Glad you are finding the posts helpful. I am pretty new to Identity Server as well and these posts are me documenting what I have learned.

  2. Hello and thanks for this nice series introducing IdentityServer 4.

    I have a question related to ASPNET CORE hosting an Angular 4 app using Hybrid Grants.
    – Why do I still need to register the Angular app in IdentityServer clients?
    – Why do I still need to register the Angular app in IdentityServer as Implicit Grant?
    – Isn’t enough to register the MVC app as HybridWithClientCredentials so that no tokens are sent to browser, instead ASPNETCORE will handle things and save the tokens on server-side. Then, any access to any page on Angular app, would be first routed via ASPNETCORE and authenticated, etc.


    1. I recommend asking this question in the Identity Server repo or on StackOverflow. I’m still learning all this stuff and don’t feel I can give you the best answer.

Leave a Reply

Your email address will not be published. Required fields are marked *