{"id":27852,"date":"2020-01-01T00:00:00","date_gmt":"2019-12-31T23:00:00","guid":{"rendered":"https:\/\/blexin.com\/angular-microservices-e-autenticazione\/"},"modified":"2021-05-20T18:45:19","modified_gmt":"2021-05-20T16:45:19","slug":"angular-microservices-and-authentication","status":"publish","type":"post","link":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/","title":{"rendered":"Angular, Microservices and Authentication"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"27832\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/attachment\/image00-16-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image00-16\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=300%2C178&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-27832\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I am working on a new project, for which I need to authenticate an Angular client to access to a set of microservices. The permission to access each microservices depends on the current user privileges, and I need to be independent of the authentication mechanism.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can divide up the problem into two main subproblems: authentication and authorization. We use the existent standards and the right technologies to implement them. To manage user authentication, we can use OAuth and OpenId, which make us independent from the authority implementation. For the sake of simplicity, we can start with Microsoft Identity Server 4, an open-source project that implements OAuth 2.0 and OpenID Connect for ASP.NET Core.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s start with the creation of the sample project structure, with a folder for the Identity Server project, a folder for the Angular client and two folders for two generic microservices:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"449\" data-attachment-id=\"27835\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/attachment\/image01-12-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12.png?fit=782%2C449&amp;ssl=1\" data-orig-size=\"782,449\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image01-12\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12.png?fit=300%2C172&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12.png?fit=782%2C449&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12.png?resize=782%2C449&#038;ssl=1\" alt=\"\" class=\"wp-image-27835\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12.png 782w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-12-480x276.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 782px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">We can create the Angular client with the usual command of the Angular CLI (<strong>ng new angular-client<\/strong>) and the two microservices with the usual command of the .NET CLI (<strong>dotnet new webapi<\/strong>). To create the Identity Server project, instead, we need to install the templates for Identity Server 4:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>dotnet new -i IdentityServer4.Templates<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This command installs various templates, and we can choose the&nbsp;<strong>is4inmem<\/strong>&nbsp;template, which creates a project that stores in memory all the configuration data. Using the in-memory storage, we can learn the basics of the framework without introducing the storage complexity (you can use the&nbsp;<strong>is4ef<\/strong>&nbsp;template if you prefer to store the configuration data using Entity Framework).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We need to introduce three concepts to understand how Identity Server works:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>Identity Resource<\/strong>: it is information like User ID, phone number, or email address that we can add to the user identity, and include them in the user token.<\/li><li><strong>API Resource<\/strong>: it defines the APIs that we can protect<\/li><li><strong>Client<\/strong>: it represents a client like our Angular client, and it wants to access to the resources protected by the system.<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">We can find the base configuration of the template in the Config.cs file. We decide to store this information in memory for simplicity\u2019s sake, but you can store them in a database.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We must adapt the template code to our needs. As Identity Resource, we need only the OpenID resource that represents the unique ID for the user, that in the OpenID Connect specification is called subject ID:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static IEnumerable&lt;IdentityResource&gt; Ids =&gt;\n\u00a0\u00a0\u00a0\u00a0new IdentityResource&#x5B;]\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new IdentityResources.OpenId()\n\u00a0\u00a0\u00a0\u00a0}; \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">As APIs, we need to define our microservices:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static IEnumerable&lt;ApiResource&gt; Apis =&gt;\n\u00a0\u00a0\u00a0\u00a0new ApiResource&#x5B;]\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new ApiResource(&quot;microservice1&quot;, &quot;My Microservice #1&quot;),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new ApiResource(&quot;microservice2&quot;, &quot;My Microservice #2&quot;)\n\u00a0\u00a0\u00a0\u00a0};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The most important passage is the definition of clients. In our case, we need only one client definition, but you can define all the clients you need. Our Angular client uses the data that we set to connect to the Identity Server and obtain the token to access the protected resources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each client must have a unique identifier, named ClientId, and optionally can have a ClientName. We can set the URI from which the client requires the connection, named ClientUri, and a password, called ClientSecrets, to authenticate it. We can choose if a secret is required or not, based on the type of flow, named Grant Type in the OpenID Connect specification. A Grant Type defines how a client can interact with the service that generates the token.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our example, we use the Implicit Grant Type, which transmits the token via the browser. The&nbsp;<em>Implicit<\/em>&nbsp;flow is the simplest available, and it is the most used with JavaScript clients, but it does not permit advanced features like the token refresh. You can read about others Grant Types in the&nbsp;<a href=\"http:\/\/docs.identityserver.io\/en\/aspnetcore2\/topics\/grant_types.html\" target=\"_blank\" rel=\"noreferrer noopener\">official documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our example, we choose that it does not have a ClientSecret (RequireClientSecret = false) because a JavaScript client runs on the user browser, then it is easily retrievable from the code. After the login and the logout operations, we can specify a list of URIs to redirect the user from which the client can choose. We can also enable CORS calls (<a href=\"https:\/\/developer.mozilla.org\/it\/docs\/Web\/HTTP\/CORS\" target=\"_blank\" rel=\"noreferrer noopener\">&nbsp;https:\/\/developer.mozilla.org\/it\/docs\/Web\/HTTP\/CORS&nbsp;<\/a>) from the client URI and allow the send of the access token via the browser (AllowAccessTokenViaBrowser = true). To finish the configuration, we need to specify for which&nbsp;<strong>scopes<\/strong>&nbsp;the client requires the token. In our case the OpenID info (the subject identifier) and the API Resources defined:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static IEnumerable&lt;Client&gt; Clients =&gt;\n\u00a0\u00a0\u00a0\u00a0new Client&#x5B;]\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Client\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ClientId = &quot;AngularClient&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ClientName = &quot;Angular Client&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ClientUri = &quot;http:\/\/localhost:4200&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0RequireClientSecret = false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0RequireConsent = false,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AllowedGrantTypes = GrantTypes.Implicit,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0RedirectUris = { &quot;http:\/\/localhost:4200&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PostLogoutRedirectUris = { &quot;http:\/\/localhost:4200\/&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AllowedCorsOrigins = { &quot;http:\/\/localhost:4200&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AllowAccessTokensViaBrowser = true,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AccessTokenLifetime = 3600,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0AllowedScopes = { &quot;openid&quot;, &quot;microservice1&quot;, &quot;microservice2&quot; }\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \n\u00a0\u00a0\u00a0\u00a0\u00a0};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We are now ready to define our user accounts (we use the memory as storage to simplify the code). We can use the class TestUser, provided by the framework, and configured in the TestUsers.cs file (under the Quickstart folder):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static List&lt;TestUser&gt; Users = new List&lt;TestUser&gt;\n{\n\u00a0\u00a0\u00a0\u00a0\u00a0new TestUser{SubjectId = &quot;1&quot;, Username = &quot;michele&quot;, Password = &quot;michele&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0new TestUser{SubjectId = &quot;2&quot;, Username = &quot;antonio&quot;, Password = &quot;antonio&quot; }\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s time to integrate the Angular Client, where we can use&nbsp;<strong>oidc-client<\/strong>&nbsp;(<a href=\"https:\/\/github.com\/IdentityModel\/oidc-client-js\" target=\"_blank\" rel=\"noreferrer noopener\">&nbsp;https:\/\/github.com\/IdentityModel\/oidc-client-js&nbsp;<\/a>), a ready-to-use library that helps us connecting to the Identity authority to retrieve the user token and accessing to the protected APIs:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>npm i oidc-client<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To simplify and abstract all the operation with this library, we can create an Angular Service like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { Injectable } from &#039;@angular\/core&#039;;\nimport { environment } from &#039;src\/environments\/environment&#039;;\nimport { UserManager, User } from &#039;oidc-client&#039;;\n\u00a0\n@Injectable({providedIn: &#039;root&#039;})\nexport class AuthService {\n\u00a0\n\u00a0\u00a0\u00a0\u00a0public user: User;\n\u00a0\u00a0\u00a0\u00a0private userManager: UserManager;\n\u00a0\n\u00a0\u00a0\u00a0\u00a0constructor() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.userManager = new UserManager({\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0authority: environment.authority,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0client_id: environment.clientId,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0redirect_uri: environment.redirectUri,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0response_type: environment.responseType,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0scope: environment.scope\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0login() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return this.userManager.signinRedirect();\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0async completeAuthentication() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.user = await this.userManager.signinRedirectCallback();\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0isAuthenticated(): boolean {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return this.user != null &amp;&amp; !this.user.expired;\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0signout() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.userManager.signoutRedirect();\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The library provides us two objects: the&nbsp;<em>UserManager<\/em>&nbsp;for managing the operations login and logout and the&nbsp;<em>User<\/em>&nbsp;for storing the token information. The login performs in two stages: a redirect to the login page, and a token recovery after the redirect. The&nbsp;<em>login()<\/em>&nbsp;method executes the first stage, the&nbsp;<em>completeAuthentication()<\/em>&nbsp;executes the second stage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can use the environments Angular CLI management to configure our development variables:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nexport const environment = {\n\u00a0\u00a0\u00a0\u00a0production: false,\n\u00a0\u00a0\u00a0\u00a0authority: &#039;http:\/\/localhost:5000&#039;,\n\u00a0\u00a0\u00a0\u00a0clientId: &#039;AngularClient&#039;,\n\u00a0\u00a0\u00a0\u00a0redirectUri: &#039;http:\/\/localhost:4200&#039;,\n\u00a0\u00a0\u00a0\u00a0responseType: &#039;id_token token&#039;,\n\u00a0\u00a0\u00a0\u00a0scope: &#039;openid microservice1 microservice2&#039;,\n\u00a0\u00a0\u00a0\u00a0microservice1Url: &#039;http:\/\/localhost:5002\/WeatherForecast&#039;,\n\u00a0\u00a0\u00a0\u00a0microservice2Url: &#039;http:\/\/localhost:5003\/WeatherForecast&#039;\n};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">As we can see, we set the Authority with the address of the Identity Server application, choose the AngularClient as clientId to connect to the server, and require a token (responseType: &#8216;id_token token&#8217;) with the OpenID, microservice1, and microservice2 as scopes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we can use the AuthService with the APP_INITIALIZER provider (<a href=\"https:\/\/angular.io\/api\/core\/APP_INITIALIZER\" target=\"_blank\" rel=\"noreferrer noopener\">&nbsp;https:\/\/angular.io\/api\/core\/APP_INITIALIZER&nbsp;<\/a>). Usually, I create an AppService with a specific method to do all the needed works to startup an Angular client. In this case, the implementation is very simple:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { Injectable } from &#039;@angular\/core&#039;;\nimport { AuthService } from &#039;.\/auth.service&#039;;\n\u00a0\n@Injectable({providedIn: &#039;root&#039;})\nexport class AppService {\n\u00a0\n\u00a0\u00a0\u00a0\u00a0constructor(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private authService: AuthService) { }\n\u00a0\n\u00a0\u00a0\u00a0\u00a0initApp(): Promise&lt;any&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return new Promise(async (resolve, reject) =&gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!this.authService.isAuthenticated()) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (window.location.href.indexOf(&#039;id_token&#039;) &gt;= 0) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await this.authService.completeAuthentication();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0resolve();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else if (window.location.href.indexOf(&#039;error&#039;) &gt;= 0) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reject();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return this.authService.login();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">When the Angular client starts, I check if the user is already authenticated. If it is not, I have three possibilities: the user not started authenticated stage yet, I am returning from the login redirect with success, or I am returning from the login redirect with an error. I understand from the URL which is the current state:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>f the URL contains a string &#8216;id_token&#8217;, I am returning from the login with success, and I can complete the login calling the&nbsp;<em>completeAuthentication() method<\/em>;<\/li><li>if the URL contains a string &#8216;error&#8217; the login is completed with an error;<\/li><li>If the URL does not contain anything, I can call the<em>&nbsp;login()<\/em>&nbsp;method to redirect the user to the login page.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Now, we are ready to use the retrieved token when calling the application microservices. The best way to do it in Angular is an interceptor to add the token on all requests:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { Injectable } from &#039;@angular\/core&#039;;\nimport { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from &#039;@angular\/common\/http&#039;;\nimport { Observable } from &#039;rxjs&#039;;\nimport { AuthService } from &#039;.\/auth.service&#039;;\n\u00a0\n@Injectable()\nexport class AuthInterceptor implements HttpInterceptor {\n\u00a0\n\u00a0\u00a0\u00a0\u00a0constructor(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private authService: AuthService) {}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0intercept(req: HttpRequest&lt;any&gt;, next: HttpHandler): Observable&lt;HttpEvent&lt;any &gt; &gt; {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const headers = req.headers\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.set(&#039;Content-Type&#039;, &#039;application\/json&#039;)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.set(&#039;Authorization&#039;, `${this.authService.user.token_type}\u00a0 ${this.authService.user.access_token}`);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const authReq = req.clone({ headers });\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return next.handle(authReq);\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We use the access token (that is a simple JSON Web Token or shortly a JWT Token) in the Authorization header. The token_type, in our case, is the usual &#8216;Bearer&#8217;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now we can configure all in the AppModule:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { BrowserModule } from &#039;@angular\/platform-browser&#039;;\nimport { NgModule, APP_INITIALIZER } from &#039;@angular\/core&#039;;\nimport { HttpClientModule, HTTP_INTERCEPTORS } from &#039;@angular\/common\/http&#039;;\n\u00a0\nimport { AppComponent } from &#039;.\/app.component&#039;;\nimport { AppService } from &#039;.\/app.service&#039;;\nimport { AuthInterceptor } from &#039;.\/auth.interceptor&#039;;\n\u00a0\nexport function initApp(appService: AppService) {\n\u00a0return () =&gt; appService.initApp();\n}\n\u00a0\n@NgModule({\n\u00a0declarations: &#x5B; AppComponent ],\n\u00a0imports: &#x5B; BrowserModule, HttpClientModule ],\n\u00a0providers: &#x5B;\n\u00a0\u00a0\u00a0\u00a0{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },\n\u00a0\u00a0\u00a0\u00a0{ provide: APP_INITIALIZER, useFactory: initApp, deps: &#x5B;AppService], multi: true }\n\u00a0],\n\u00a0bootstrap: &#x5B;AppComponent]\n})\nexport class AppModule { }\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The AppComponent is just a list of calls for each available microservice, and a sign out button:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&lt;h2&gt;Angular Client &lt;\/h2&gt;\n&lt;h3&gt;Available Microservices: &lt;\/h3&gt;\n&lt;ul&gt;\n\u00a0&lt;li &gt;Microservice 1: &lt;button type=&quot;button&quot; (click)=&quot;callMicroservice1()&quot;&gt;Call&lt;\/button &gt; &lt;\/li&gt;\n\u00a0&lt;li &gt;Microservice 2: &lt;button type=&quot;button&quot; (click)=&quot;callMicroservice2()&quot;&gt;Call&lt;\/button &gt; &lt;\/li&gt;\n&lt;\/ul&gt;\n&lt;button type=&quot;button&quot; (click)=&quot;signout()&quot;&gt;Signout &lt;\/button&gt;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This is the code of the AppComponent:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nimport { Component, OnInit } from &#039;@angular\/core&#039;;\nimport { Location, LocationStrategy, PathLocationStrategy } from &#039;@angular\/common&#039;;\nimport { HttpClient } from &#039;@angular\/common\/http&#039;;\nimport { environment } from &#039;src\/environments\/environment&#039;;\nimport { AuthService } from &#039;.\/auth.service&#039;;\n\u00a0\n@Component({\n\u00a0selector: &#039;app-root&#039;,\n\u00a0templateUrl: &#039;.\/app.component.html&#039;,\n\u00a0providers: &#x5B;Location, {provide: LocationStrategy, useClass: PathLocationStrategy}],\n})\nexport class AppComponent {\n\u00a0\u00a0\u00a0\u00a0constructor(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0location: Location,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private authService: AuthService,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0private httpClient: HttpClient) {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0location.replaceState(&#039;\/&#039;);\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0callMicroservice1() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.httpClient.get(environment.microservice1Url)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.subscribe(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data =&gt; alert(&#039;SUCCESS: &#039; + JSON.stringify(data)),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0error =&gt; alert(&#039;ERROR: &#039; + JSON.stringify(error)));\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0callMicroservice2() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.httpClient.get(environment.microservice2Url)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.subscribe(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data =&gt; alert(&#039;SUCCESS: &#039; + JSON.stringify(data)),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0error =&gt; alert(&#039;ERROR: &#039; + JSON.stringify(error)));\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0signout() {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0this.authService.signout();\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Note the use of the location service: we receive the token information via the URL, so we need to clear these data and remove the call from the browser history. The&nbsp;<em>location.replaceState()<\/em>&nbsp;method replaces the top item on browser history stack and normalizes the given URL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We are ready for the microservices configuration, where we need to configure the authentication process using JWT. We need to install the&nbsp;<em>Microsoft.AspNetCore.Authentication.JwtBearer<\/em>&nbsp;package and add to the&nbsp;<em>ConfigureService()<\/em>&nbsp;method of the&nbsp;<em>Startup<\/em>&nbsp;class, the following code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nservices.AddAuthentication(options =&gt;\n\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;\n\u00a0\u00a0\u00a0\u00a0\u00a0options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;\n\u00a0}).AddJwtBearer(o =&gt;\n\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0o.Authority = &quot;http:\/\/localhost:5000&quot;;\n\u00a0\u00a0\u00a0\u00a0\u00a0o.Audience = &quot;microservice1&quot;;\n\u00a0\u00a0\u00a0\u00a0\u00a0o.RequireHttpsMetadata = false;\n});\n\u00a0\nservices.AddAuthorization();\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In the&nbsp;<em>Configure()<\/em>&nbsp;method, we need to add the<em>UseAuthentication<\/em>&nbsp;middleware to enable the authentication process:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>app.UseAuthentication();<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The &#8216;webapi&#8217; template creates a WeatherForecast API with some sample data that we can protect using the&nbsp;<em>Authorize<\/em>&nbsp;attribute:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;ApiController]\n&#x5B;Route(&quot;&#x5B;controller]&quot;)]\n&#x5B;Authorize]\npublic class WeatherForecastController : ControllerBase\n{\n\u00a0\u00a0\u00a0\u00a0...\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">To simplify the debug, we set the microservice1 to run on the 5002 port and the microservice2 to run on the 5003 port. To do this, we can change the launchSettings.json in the Properties folder of each microservice:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&quot;microservice1&quot;: {\n\u00a0\u00a0\u00a0\u00a0\u00a0&quot;commandName&quot;: &quot;Project&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0&quot;launchBrowser&quot;: true,\n\u00a0\u00a0\u00a0\u00a0\u00a0&quot;launchUrl&quot;: &quot;weatherforecast&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0&quot;applicationUrl&quot;: &quot;http:\/\/localhost:5002&quot;,\n\u00a0\u00a0\u00a0\u00a0\u00a0&quot;environmentVariables&quot;: {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&quot;ASPNETCORE_ENVIRONMENT&quot;: &quot;Development&quot;\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We can run our four projects and open the browser at localhost:4200. If everything runs correctly, the client redirects us to the localhost:5000 for the login stage, and after the login, Identity Server redirects us to the localhost:4200 with the token_id in the URL.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"787\" height=\"1024\" data-attachment-id=\"27844\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/attachment\/image02-11-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-11.png?fit=1151%2C1497&amp;ssl=1\" data-orig-size=\"1151,1497\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image02-11\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-11.png?fit=231%2C300&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-11.png?fit=787%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-11.png?resize=787%2C1024&#038;ssl=1\" alt=\"\" class=\"wp-image-27844\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to see the request with the retrieved token, you can use the Network panel of the Chrome Developer Tools:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"668\" data-attachment-id=\"27846\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/attachment\/image03-10-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10.png?fit=1149%2C749&amp;ssl=1\" data-orig-size=\"1149,749\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image03-10\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10.png?fit=300%2C196&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10.png?fit=1024%2C668&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10.png?resize=1024%2C668&#038;ssl=1\" alt=\"\" class=\"wp-image-27846\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10-1024x668.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10-980x639.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-10-480x313.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Very cool! But I want to add almost another feature: enable access to each microservice based on the current user. We have two users, Michele and Antonio, and now I want to forbid the access to the microservice2 to Antonio. I can do this in different ways, but I prefer the use of the user Claims because it enables advanced scenarios for the access granularity.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the class TestUsers, we add some claims to the users:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic static List&lt;TestUser&gt; Users = new List&lt;TestUser&gt;\n{\n\u00a0\u00a0\u00a0\u00a0new TestUser { SubjectId = &quot;1&quot;, Username = &quot;michele&quot;, Password = &quot;michele&quot;, \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Claims = \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Claim(&quot;microservice1&quot;, &quot;admin&quot;),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Claim(&quot;microservice2&quot;, &quot;admin&quot;),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0},\n\u00a0\u00a0\u00a0\u00a0new TestUser { SubjectId = &quot;2&quot;, Username = &quot;antonio&quot;, Password = &quot;antonio&quot;, \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Claims = \n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Claim(&quot;microservice1&quot;, &quot;user&quot;),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0};\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">As we can see, Michele has two claims, microservice1 and microservice2, whereas Antonio has only one claim, microservice1. We need these claims to be added to the access token, but Identity Server does not do this for us. We can execute custom code during the token creation implementing a custom ProfileService from the&nbsp;<em>IProfileService<\/em>&nbsp;interface. The IProfileService interface requires the implementation of two methods: the&nbsp;<em>GetProfileDataAsync<\/em>, called during the token creation to retrieve the user profile, and the&nbsp;<em>IsActiveAsync<\/em>&nbsp;method, that permits to personalize the criteria for which the user is active or not. The GetProfileDataAsync method provides us the&nbsp;<em>ProfileDataRequestContext<\/em>&nbsp;that exposes the<em>&nbsp;IssuedClaims<\/em>&nbsp;list for adding additional claims to the profile:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nusing System.Linq;\nusing System.Threading.Tasks;\nusing IdentityServer4.Models;\nusing IdentityServer4.Quickstart.UI;\nusing IdentityServer4.Services;\n\u00a0\nnamespace identityserver.Services\n{\n\u00a0\u00a0\u00a0\u00a0public class ProfileService : IProfileService\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public Task GetProfileDataAsync(ProfileDataRequestContext context)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0string sub = context.Subject.FindFirst(&quot;sub&quot;).Value;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var user = TestUsers.Users.FirstOrDefault(x =&gt; x.SubjectId == sub);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (var claim in user.Claims)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0context.IssuedClaims.Add(claim);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Task.CompletedTask;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0public Task IsActiveAsync(IsActiveContext context)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0context.IsActive = true;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return Task.CompletedTask;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now we need to add the custom profile service in the ConfigureService() of the Identity Server project:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>builder.AddProfileService&lt;ProfileService&gt; ();<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thanks to these changes, the access token for the current user contains the added claims that we can use to discriminate the access to our microservices. We have to return to the ConfigureService() of the microservices and change the AddAuthorization, adding an&nbsp;<em>Authorization Policy<\/em>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nservices.AddAuthorization(options = &gt;\n{\n\u00a0\u00a0\u00a0\u00a0options.AddPolicy(&quot;ApiUser&quot;, policy =&gt; policy.RequireClaim(&quot;microservice1&quot;));\n}); \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The Authorization Policies is a new mechanism introduced in the .NET Core for controlling the access to API through custom rules. In our case, we define a new policy called &#8220;ApiUser&#8221; that checks the presence of the claim &#8216;microservice1&#8217; in the user profile. Now we can change the Authorize attribute on the WeatherForecast controller to apply the new policy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;ApiController]\n&#x5B;Route(&quot;&#x5B;controller]&quot;)]\n&#x5B;Authorize(&quot;ApiUser&quot;)]\npublic class WeatherForecastController : ControllerBase\n{\n\u00a0\u00a0\u00a0\u00a0...\n} \n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">After doing the same operations for the microservice2, we can run the application and check if Antonio can access to the microservice2:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"818\" height=\"1024\" data-attachment-id=\"27850\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/attachment\/image04-11-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image04-11.png?fit=1196%2C1498&amp;ssl=1\" data-orig-size=\"1196,1498\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image04-11\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image04-11.png?fit=240%2C300&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image04-11.png?fit=818%2C1024&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image04-11.png?resize=818%2C1024&#038;ssl=1\" alt=\"\" class=\"wp-image-27850\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As you can imagine, we can implement very sophisticated scenarios using OAuth, OpenID, and the Authorization Policies of the .NET Core. Identity Server can help us to try different options and choose the correct flow for our application. All the code is available here:&nbsp;<a href=\"https:\/\/github.com\/apomic80\/angular-microservices-identityserver\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/apomic80\/angular-microservices-identityserver&nbsp;<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Happy Coding!<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Authenticating an Angular client to access to a microservices architecture using OAuth and OpenID with Identity Server 4<\/p>\n","protected":false},"author":196716248,"featured_media":27832,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false},"categories":[688637524],"tags":[688637390,688637384,688637428],"class_list":["post-27852","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-en","tag-angular-en","tag-c-en","tag-microservices-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular, Microservices and Authentication - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular, Microservices and Authentication - Blexin\" \/>\n<meta property=\"og:description\" content=\"Authenticating an Angular client to access to a microservices architecture using OAuth and OpenID with Identity Server 4\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2019-12-31T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-20T16:45:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Michele Aponte\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michele Aponte\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/\"},\"author\":{\"name\":\"Michele Aponte\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"headline\":\"Angular, Microservices and Authentication\",\"datePublished\":\"2019-12-31T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:45:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/\"},\"wordCount\":1848,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-16.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"Angular\",\"C#\",\"Microservices\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/\",\"name\":\"Angular, Microservices and Authentication - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-16.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2019-12-31T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:45:19+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-16.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/image00-16.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-microservices-and-authentication\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular, Microservices and Authentication\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\",\"name\":\"Michele Aponte\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"caption\":\"Michele Aponte\"},\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/author\\\/michele-aponteblexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular, Microservices and Authentication - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/","og_locale":"en_US","og_type":"article","og_title":"Angular, Microservices and Authentication - Blexin","og_description":"Authenticating an Angular client to access to a microservices architecture using OAuth and OpenID with Identity Server 4","og_url":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/","og_site_name":"Blexin","article_published_time":"2019-12-31T23:00:00+00:00","article_modified_time":"2021-05-20T16:45:19+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Michele Aponte","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Michele Aponte","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/"},"author":{"name":"Michele Aponte","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"headline":"Angular, Microservices and Authentication","datePublished":"2019-12-31T23:00:00+00:00","dateModified":"2021-05-20T16:45:19+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/"},"wordCount":1848,"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","keywords":["Angular","C#","Microservices"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/","url":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/","name":"Angular, Microservices and Authentication - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","datePublished":"2019-12-31T23:00:00+00:00","dateModified":"2021-05-20T16:45:19+00:00","author":{"@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"breadcrumb":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-microservices-and-authentication\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/en\/"},{"@type":"ListItem","position":2,"name":"Angular, Microservices and Authentication"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/en\/#website","url":"https:\/\/blexin.com\/en\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005","name":"Michele Aponte","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","caption":"Michele Aponte"},"url":"https:\/\/blexin.com\/en\/author\/michele-aponteblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image00-16.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7fe","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/27852","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/users\/196716248"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/comments?post=27852"}],"version-history":[{"count":5,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/27852\/revisions"}],"predecessor-version":[{"id":31953,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/27852\/revisions\/31953"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media\/27832"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media?parent=27852"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/categories?post=27852"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/tags?post=27852"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}