Identity Server: Deploy to Azure

This post is going to cover taking the existing set of applications we have been using to learn about Identity Server and deploying them to Azure. The starting point of the code can be found here.

Prep Work

The applications as they stand from the link above are not ready to be pushed to Azure most due to some configuration changes that are needed. We will go through each of the applications and take the hard-coded values and move them to  appsettings.json.

API Application Configuration

The API application needs two configuration values for the address of the Identity Application and the address of the Client Application. The following two lines need to be added to the application’s  appsettings.json file.

Then in the  Startup class, the values need to be used. The Identity Server address is used in the JWT Bearer setup.

Then the Client address is used in the CORS setup.

Identity Application Configuration

The Identity application needs a configuration value for the address of the address of the Client Application. The following line needs to be added to the application’s  appsettings.json file.

Next, the  Config class needs a reference to configuration passed into the  GetClients function.

Next, the references to  http://localhost:5002 need to be replaced with the value from the configuration. The following is one example.

Identity Application Entity Framework

As part of publishing this set of applications, this example is going to use Azure SQL and right now the application is set up to use SQLite. In the  Startup class replace  UseSqlite with  UseSqlServer. The following is an example of one of the needed replacements.

When switching database providers make sure to delete and recreate your database migrations. I didn’t to begin with and it cost me a lot of time in changing down a strange error which this post covers.

Client Application Configuration

The Client application needs two configuration values for the address of the Identity Application and the address of the API Application. The following two lines need to be added to the application’s  appsettings.json file.

Then in the  Startup class, the Identity Server Address needs to be used in the  AddOpenIdConnect call.

Next, the configuration values need to be passed to the Angular application. This process ended up being harder to figure out that I had anticipated and turned into a full blog post on its own. See this post for the details. The code for all the changes will also be on GitHub in case you need to the the diff for the client application.

Publish to Azure

Right-click on the Identity Application and select Publish.

This will show the Publish screen which provides the option to publish to Azure. We don’t have an existing App Service so we are going to create a new one. This page in the official docs explains all the options available on the publish screen. Click the publish button to continue.

The next screen that shows is the Create App Service Screen. I used all the default values and created a new Resource Group and App Service Plan. Keep in mind that the resource group and plan will be reused for the remaining two applications we are looking deploy. The only thing that will change between the applications on this screen will be the App Name.

The services tab looks like the following.

Next in the additional resources box lets hit the plus button next to SQL Database since our group of applications is going to need somewhere to store data. This will take us to the Configure SQL Database screen.

Since I don’t already have a SQL Server setup I am going to hit the New button to add one. That results in the next screen where you enter a name for the server as well as a username and password. After entering the required information click OK.

This will put you back on the configure database screen with most of it filled out. Make sure to set the database name you want to use.

Finally back on the Create App Service screen, you will see all the resources that you selected and configured. When you are satisfied with what you see click the Create button and let Azure do its magic.

When it is done you will see the profile now listed on the Publish page.

The above needs to be repeated for both the API and Client Applications, but using the Resource Group and App Service plan created above. Each profile should use a unique application name.

Identity Application Azure Configuration

The Identity Application needs access to the database that we created above. This means we need to set the  DefaultConnection. The first step is to determine what the connection string should be. On the Azure Portal in your list of resources select the SQL database that we created above.

On the next page copy the provided connection string. Now navigate to the Identity App Service and under the Settings section select Application settings. Scroll down and find the Connection strings section and enter the copied value as the DefaultConnection.

Just above the Connection strings section we also need to enter a few values in the App settings section. For the Identity Application, we need the Twitter key and secret as well as the address of the client application. The following is a screenshot minus the actual values.

For the ClientAddress use the URL found in the Overview of the Client App’s App Service page.

API Application Azure Configuration

From the list of resources select the API App’s App Service page and in the Settings section select Application settings. In the App settings section add values for  IdentityServerAddress and  ClientAddress. As with the  ClientAddress above the URLs for each application can be found on their respective App Service pages.

Client Application Azure Configuration

From the list of resources select the Client App’s App Service page and in the Settings section select Application settings. In the App settings section add values for  IdentityServerAddress and  ApiAddress.

Wrapping Up

At this point, you should be able to load up the application at the client address provided by Azure and have a working application. Overall the deployment to Azure was pretty easy. Getting the applications prepared to be deployed was a bit more challenging and sent me down a couple of rabbit holes. The code in its final state can be found here.

Pass ASP.NET Core Appsettings Values to Angular

As part of getting my set of Identity Server 4 sample applications to run in Azure, I needed a way in the Client Application to pass some configuration values from  appsettings.json to the Angular front end that could be used both during server-side rendering and client-side rendering. This application is using JavaScriptServices. This solution may need tweaking if your application isn’t using JavaScriptServices. The code for the client application can be found here.

Settings

In this example, we need to pass the address of our Identity Server and API from  appsettings.json to Angular. The following is the settings file for this example.

Providing Configuration Data to Angular

In this application, Angular is loaded from the index action of the home controller. This view can be found in the  Views/Home folder in the  Index.cshtml file. The following is the file before any changes.

The first change needed is to inject the configuration data using ASP.NET Core’s DI system. Add the following two lines at the top of the file.

Now the configuration data from the application is available to this view. Next, we need to pull a couple of values out of the configuration data and pass it to the Angular application. To do this we are going to use the  asp-prerender-data tag helper. You can read more about it in the official docs. The idea is you construct an object which is then serialized and stored in  params.data. In our example, we are passing the URLs for the Identity and API Applications.

The above is creating a new object with an  apiUrl property and an  identityUrl property. The following is the full completed view for reference.

Angular Server-Side Boot

When Angular gets prerendered on the server-side it runs the code in the  boot.server.ts file. This is where we will set up the providers needed on for the server side prerender. This is the bit that I missed for the longest time when trying to get this example going. I kept trying to find a way to add the providers in the  app.module.server.ts file. Add any providers you need to the  providers constant. For example, the following is passing URLs for an API and Identity Server in addition to the defaults provided by JavaScriptServices.

Lower in the same file we can pass through the configuration values to the client side render as globals on the window object. To do this add a  globals property to the object being passed to the  resolve call.

The above will have the URLs as part of a single object, but you could have each URL as its own property if you prefer.

Angular Client-Side

Now that the server-side has providers for API URL and Identity URL we need to provide the client-side with the same capabilities. These changes will be in the  app.module.browser.ts file. The first step is to add providers for each.

Next, we need functions to return the URLs from the  url_Config property of the window object which the following two functions do.

Wrapping Up

With the above, you can now use your configuration values from ASP.NET Core and pass them through to your Angular application. In hindsight, the process is pretty simple, but getting to that point took me much longer to figure out than I would like to admit. I hope this post saves you some time!

Identity Server: External Authentication using Twitter

This post is going to cover adding authentication using Twitter to the same project that has been used in all of my IdentityServer examples. The same basic idea would apply to almost any third party authentication setup so this should give you a good starting point for any integration. The starting point of the code can be found here.

Create Twitter App

Before any code changes create a new application on Twitter via this page. Click Create New App to begin the process.

On the Create an application page enter all the requested information. Note that the website won’t allow a localhost address. If you don’t have a real address for your application just enter a random URL as I did here. When finished click Create your Twitter application.

Now that we have an application click on the Keys and Access Tokens tab. We will need both the Consumer Key and Consumer Secret when we get to the Identity Application.

Identity Application Changes

Now that we have a Twitter application ready to go let us dive into the changes needed to the Identity Application. The first step is to add a reference to Microsoft.AspNetCore.Authentication.Twitter via NuGet.

Next in the  ConfigureServices function of the  Startup class after  app.UseIdentityServer() add the following.

The first three options should a straight forward enough. The next two are the values from the Twitter application I mentioned above. In this example, I am storing the values using User Secrets which get pulled out of configuration. For more details on how to set up secrets, you can see this post.

The above are all the changes required. The Identity Application will now allow users to auth using Twitter.

Logging in using Twitter

As you can see below the login page now has a button for Twitter.

When the user chooses to log in using Twitter they are shown the following page where they must approve access to their Twitter account from your application.

If this is the first time a user has logged in with Twitter they will be prompted to enter an email address to finish registration.

Wrapping up

As you can see adding external authentication is super simple. Check out the Microsoft Docs on Twitter Auth (ASP.NET Core 2.0 so look out for differences if you are not on the preview bits) and IdentityServer Docs on External Auth for more information.

The finished code can be found here.

 

Identity Server: Changing Angular OpenID Connect Clients

Thanks to Andrew Stegmaier opening this issue on the repo that goes with my IdentityServer exploration I was made aware of a certified OpendID Connect client specifically written for Angular (4+). The angular-auth-oidc-client was created by damienbod. This post is going to cover the transition to this new client. The starting point of the code can be found here. All the changes discussed in this post take place in the ClientApp project.

Package Changes

In  package.json the following changes need to be made using your package manager of choice or manually changing the fill and doing a restore.

App Module Changes

Both  app.module.client.ts and  app.module.server.ts got a little cleanup to remove the duplicate provider code. The following lines were deleted from both files.

The  providers array moved to using providers imported from  app.module.shared.ts.

Next, in  app.module.shared.ts the following imports were removed.

Then, the following import for the OpenId Connect client was added.

In the  declarations array  CallbackComponent was removed. In the  imports array  AuthModule.forRoot() was added. The route for  CallbackComponent was removed and the  canActivate condition was removed from the  fetch-data route. Finally, the  providers section is reduced to only the  AuthService. That was a lot of changes, so I am including the full finished class below.

File Deletions

The following files were completely removed. Some of them may come back in a different form, but for the moment the functions they were handling are being dealt with in a different way.

Auth Service

The  AuthService class was pretty much rewritten since it is at the core of the interaction with the OpenId Connect client. It still contains pretty much all the functionality as before just using the new client. The following is most of the class. I removed all of the HTTP calls except for  get to save space.

It doesn’t show the best in the world here so be sure and check it out on GitHub. All the IdentityServer configuration is done in the  constructor using the  OpenIDImplicitFlowConfiguration class.

Navigation Component

The  NavMenuComponent class now needs some changes to match the new  AuthService. First, the following change to the imports.

The  AuthService class now provides the ability to subscribe to changes in the user’s authorization. To handle the subscription and unsubscription the class will implement both OnInit and  OnDestroy. Here is the new class declaration.

Next, here is the implementation of ngOnInit which handles the subscription to the change in  isAuthorized.

Then,  ngOnDestroy handles the unsubscription.

The class level variable for  _loggedIn is replaced with the following two variables.

The  constructor has been greatly simplified and now only takes an instance of the  AuthService.

Finally, the  login and  logout functions have changed to match the new function names in the  AuthService class.

Navigation Component UI

In the  navmenu.component.html file, a couple of tweaks are required based on the new variable names used above. The first set is related to showing either Login or Logout.

The final change in this file was to make the link to  fetch-data only show if the user is logging instead of sending the user to an unauthorized view.

Fetch Data Component

The final changes for the conversion to the new client are in the  fetchdata.component.ts and they are only needed because of a rename of the HTTP Get helper in the  AuthService.

Wrapping Up

This change took a lot of changes, but in the long run, it is going to be a better choice since the new client is focused on Angular. Another great thing about this client is they are looking into ways to handle the first load not remembering the user is logged in due to server side rendering (issue #36).

The finished code for this post can be found here.

Identity Server: Redirect When Route Requires Logged in User

This post is going to continue where the series on IdentityServer4 left off, but I am not officially making it part of the series. There may be a few posts like this where I improve on the example applications from the series. The starting code for this post can be found here.

All the changes in the post are in the Client Application from the sample linked above. I did some cleanup on a couple of files so if you are looking for the differences keep in mind most of the changes are a result of the cleanup.

Unauthorized Component

The first step is to add a new component that will be shown to the user when they navigate to a page that requires them to be logged in but they are not. Add a  unauthorized.component.html file to the  ClientApp/app/components/unauthorized/ directory with the following contents.

This will tell the user they need to log in and provide a login button and a button to go back to the previous page. Next, add a  unauthorized.component.ts file to the same directory. This class will handle the clicks from the view.

This class is using the  AuthService for login and Angular’s  Location class to move back to the previous page.

New Component Usage

Now that this new component exists it needs to set up in  app.module.shared.ts. First, add an import.

Next, add to the  declarations array.

Finally, add unauthorized to the routes array.

Now that this new component is in place how does it get used? Well, any route that has  canActivate:[AuthGuardService] will require the user to be logged in to activate. For example, the  fetch-data route above won’t activate unless the user is logged in.

Auth Guard Service

AuthGuardService is an existing class in the project. The following is the full file.

As you can see in the  canActivate function if the user is logged in then the function returns true otherwise, the user is routed to the unauthorized component. Before the changes in this post, this dropped the user back on the home page since the unauthorized component didn’t exist.

Wrapping up

With the changes above the user gets a slightly better experience. Just being dropped on the home page wasn’t very helpful as to why that was happening. This at least lets the user know they need to log in. Another option could be to hide the navigation for the routes they don’t have access to until they log it.

The finished version of the code can be found here.

Identity Server: Calling Secured API from Angular

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
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular

This post is going to take the solution from last week, the code can be found here, and add an example of the Client Application (Angular) calling an endpoint on the API Application that requires a user with permissions.

API Application

To provide an endpoint to call with minimal changes this example just moves the SampleDataController from the Client Application to the API Application. The following is the full class.

Make special note that this class now has the  Authorize attribute applied which is the only change that was made when moving the file from the Client Application. This attribute is what will require an authorized user for all the routes this controller services.

Client Application

In the Client Application, the first step is to remove the  SampleDataController since it is now in the API Application.

Next, in the  app.module.client.ts file, add a new provider which can be used to supply the URL of the API to the rest of the Client Application. Don’t take this as best practices for injecting configuration data it is just an easy way to handle it in this application. The following is the full class without the imports (which haven’t changed) the new item is the  API_URL.

Now for the changes that need to be made to the  FetchDataComponent which is the class that will call the new API endpoint. First, add an import for the  AuthService.

Next, there are a couple of changes to the signature of the constructor. The first is to use  'API_URL' instead of  'ORIGIN_URL'. The second is to provide for injection of the  AuthService. The following is a comparison between the version of the constructor signature.

The final change is to use  authService.AuthGet with the new URL instead of  http.get.

With the above changes, the user has to be logged in or the API will respond with not authorized for the weather forecasts end point. The Client Application doesn’t have anything to provide the user with the fact they aren’t authorized at the moment, but that is outside the scope of this entry.

So far we haven’t look at the code in the  AuthService class, but I do want to explain what the  AuthGet function is doing and the related functions for put, delete, and post. These calls are wrappers around the standard Angular HTTP library calls that add authorization headers based on the logged in user. The following is the code of the  AuthGet as well as two helper functions the class uses to add the headers.

Wrapping up

It feels like this application is finally getting to the point where other development could happen if it were more than a demo, which is exciting. My thought on how this could be used for real applications is the Identity Application would stand on its own and be used by many clients. The Client Application with a few more tweaks could be used as a template for Angular applications. The completed code can be found here.

This post finishes up the core of what I set out to learn about IdentityServer, but there could be more related posts as I continue to add some polish to the current implementation of the sample solution.

Identity Server: Usage from Angular

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
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular (this post)

This post is finally going to add login from Angular in the Client Application. It has been a long time coming and will be a starting point, based on a few examples I found which I will list at the end. The starting point of the code can be found here.

API Application

In order for the Client Application to be able to call the API Application, there are some changes needed to allow cross-origin resource sharing. For more details check out this post only the basics will be covered here. First, add the following NuGet package.

  • Microsoft.AspNetCore.Cors

Next, in the  ConfigureServices function of the  Startup class add AddCors before AddMvc. The following is the full function. This allows calls to the API Application from the Client Application which is running on localhost on port 5002.

Then, in the  Configure function add  app.UseCors("default"); to make sure the default policy defined above is enforced. The following is the full function.

Identity Application

The Identity Application doesn’t have a lot of changes, but some of the configuration between it and the Client Application is what took me the bulk of time getting the code for this post setup and going.

If you are keeping up with the series then last you will know last week all the configuration data was moved to a database using Entity Framework Core. This is a bit of a problem now that I need to add a new client and the configuration data doesn’t any associated UI. To work around this I just added the new client to the  Config class in the  GetClients function and then deleted the existing database and let Entity Framework recreate it based on the new seed data. Not optimal, but I didn’t want to complicate things by adding a UI for the client setup. The following is the new client.

There are a few things in this configuration that took me some time to get right. First of all best, I have been able to tell with this style of application implicit flow is the way to go which is handled by using a  GrantTypes.Implicit for the  AllowedGrantTypes.

The next issues I ran was a cross-origin resource sharing issue. Thankfully IdentityServer makes it easy to specify what origins should be allowed using the  AllowedCorsOrigins property. In this example, we want to allow requests from the URL of our Client Application which is http://localhost:5002.

The last issue I had on was with the URIs I had set. The configuration in IdentityServer needs to exactly match the setup in the Client Application or you will have issues. I also had trouble trying to use the raw base address (http://localhost:5002) as the  PostLogoutRedirectUris so look out for that as well.

Client Application

In the client application open the  package.json file and add the following the  dependencies section.

I also updated the typescript version to 2.3.4. Be cautious when changing the version of typescript as there is an issue with Angular and typescript 2.4.x at the moment.

At this point in the process, I had to find some resources on how to continue. The following are the ones I leaned on most.

ANGULAR OPENID CONNECT IMPLICIT FLOW WITH IDENTITYSERVER4
ASP.NET Core & Angular2 + OpenID Connect using Visual Studio Code
Repo for the previous link
Repo for with example Angular OidcClient

Getting this part of the application working involved a lot of changes and instead of going in depth on everything I am going to recommend just copying in the following files for the finished example code and dig more into them after you get an example working. Here is the list of files.

  • ClientApp/ClientApp/app/components/callback/callback.component.ts
  • ClientApp/ClientApp/app/components/services/ – whole directory
  • ClientApp/ClientApp/boot-server.ts – related to a typescript error only if needed

With the above files in place, we will now focus on using the functionality they provide to log in and protect routes. To begin   app.module.client.tsapp.module.server.ts and  app.module.shared.ts all need the next set of changes. I haven’t tried it yet, but I bet this change could just be made in the shared file and used in the other two. Add the following imports.

Next, add the same three items to the array of providers (or add one if it doesn’t exist). The following is an example from the shared file.

Finally, in the shared file change any routes that you would like to require the user to be logged in to be like the following which utilizes the  canActivate of the route.

In the  navmenu.component.html which is the UI for the navigation menu add the following two options to the unordered list.

The user will only ever see one of the above options based on being logged in or not which is what the  *ngIf is doing.

The navigation view model ( navmenu.component.ts) changed a bit more. The following is the complete file.

New imports were added for the  AuthService and  GlobalEventsManager which get injected into the constructor of the class. The class also contains a _loggedIn property to track if the user is logged in or not. Finally, functions were added for  login and  logout to go with the two new links shown in the navigation.

Wrapping up

With the above, the Client Application can now log a user in and out utilizing IdentityServer from Angular. There are a lot of details in the files we just copied, but with a working sample, it is much easier to examine/customize how the process is being handled. Check back next week to see how to call the API Application from the Angular part of the Client Application.

The completed code can be found here.

Identity Server: Interactive Login using MVC

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 (this post)
Identity Server: From Implicit to Hybrid Flow
Identity Server: Using ASP.NET Core Identity
Identity Server: Using Entity Framework Core for Configuration Data
Identity Server: Usage from Angular

As before the end goal will be having authorization happen from Angular, but in the short term, the Client Application is using MVC/Razor for testing and verifications. The code as it stood before this post can be found here. If you are following along with the official docs I wrote this post while working through the Adding User Authentication with OpenID Connect quickstart.

The main point of this post is to add a way for a user to enter their username and password and get access to a page that requires authorization using the OpenID Connect protocol.

Identity Application

To enable this scenario the Identity Application will need MVC added along with some UI that will be used to handle login, permissions, and log off. First, using NuGet install the following two packages.

  • Microsoft.AspNetCore.Mvc
  • Microsoft.AspNetCore.StaticFiles

Next, in the ConfigureServices of the Startup class MVC needs to be added as a service.

Then in the Configure function use static files and use MVC should be added after the use statement for IdentityServer.

UI Changes

For the type of flow being used in this sample, the Identity Application will be in control of the login, grant, log out, and related UI. This is not a small amount of thing to get set up properly. Thankfully the IdentityServer team provides a Quickstart UI for use with the in-memory items we are currently using. The files can be downloaded from the repo linked in the previous line or an easier way is to open a Powershell prompt in the same directory of the Identity application as the Startup.cs file and run the following command.

After the download the project will contain a Quickstart folder with the needed controllers, a Views with of course the needed views, and wwwroot will have all the related files that need to be served with the views.

Config Changes

The Config class needs to be changed to return some more in-memory information to make this new process work. The first is to add a new client for MVC to the GetClients function. The following is the full function, but it is the second Client is the new one.

Notice that for the OpenID Connect implicit flow there are URLs that are needed that so this flow knows how to call back into the client application. At this point, I haven’t dug into everything that is going on in the client. The ClientId, ClientName, and URLs related properties are pretty clear. I am not 100% on the AllowedGrantTypes and AllowedScopes, but at this point, I am not going to dive into on these two options.

Next, add a  GetIdentityResources function matching the following. This fall in the same category as the two properties above, we are using them without fully digging into them.

The last change to the Config class is to add a function to return the in-memory users.

Startup Changes

The last change in the Identity Application is to add the new in-memory items to the IdentityServer service in the ConfigureServices function. The following is the full function.

Client Application

In order to get the client application to play well with the changes in the Identity Application, a few changes need to be made. First, the following NuGet packages need to be installed.

  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.OpenIdConnect

Next, in the  Configure function of the  Startup class, the application’s middleware pipeline needs some changes. Add the following line to turn off the JWT claim type mapping. This must be done before calling  UseOpenIdConnectAuthentication.

Now add in the cookie authentication middleware.

The last change is to add OpenID Connect authentication to the pipeline placed after the cookies middleware.

Notice that the URL of the authority is the URL the Identity Application runs on as well as the client ID match the one we set up in the  GetClients function of the  Config class in the Identity Application.

Identity Controller

Now that the above is set up we can switch over to the  IdentityController and add the  Authorize attribute to the  Index function.

This means if a user hits the index action of this controller and isn’t logged in they will be presented with the login page and after login, they will be redirected back to the above index action. That whole process is handled by the OpenId Connect Authentication middleware. The first time I tested the flow and it just worked was magical.

 

The final set of changes for this post is going to be added a way to log out. In the  IdentityController add a  Logout function.

Identity View Changes

The last change is to add a logout button to the  Index.cshtml found in the Views/Identity directory. At the bottom of the page, the following was added to call the  Logout action.

Wrapping Up

I already liked the idea of IdentityServer before this post, but after playing with it with the changes above it is emphasized how nice it is. I am very happy I am going down this path instead of trying to work this all out on my own. Stay tuned as this exploration will continue in future posts.

The code in the finished state can be found here.

Update

Turns out there is a bug in the code that goes with this example. In the client application’s  IdentityConroller the call to get a token is using  clientApp instead of  mvc for the client ID when requesting a token. With that change, the call to the API Application will fail since the MVC client doesn’t have access to the API scope. Look for next weeks post where API access will be added to the MVC client.

Identity Server: Sample Exploration and Initial Project Setup

This post will be a continuation of my exploration around Identity Server which was started with this post which was more of an overview of the space and my motivations for learning about Identity Server. There were a lot of things that were unclear to me as I first started looking through the samples so this post is going to communicate so of those issues and hopefully clear them up for you as well.

After this post, the follow-up post should be more focused on one thing instead of trying to cover so much information in on go.

The following are all the posts in this series.

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

Typical Sample Solution Structure

I started my exploration with the IdentityServer4.Sample repo specifically in the Quickstarts folder. For me, this was a mistake as I didn’t have a good enough grasp on the larger concepts for the code to provide proper guidance. Big surprise here, but using the docs and actually walking through the project creation was very helpful.

The code associated with this blog can be found here. The solution contains three projects.

  • ApiApp – Backend for the application and is a resource that is will require authorization to access. The API will be an ASP.NET Core Web API.
  • ClientApp – Frontend application that will be requesting authorization. This is an ASP.NET Core application that is hosting an Angular (4) app.
  • IdentityApp – This is ASP.NET Core application that is the IdentityServer and will end up authorizing users and issuing tokens for resources.

Identity Application

For the Identity application, create an ASP.NET Core Web Application using the empty template targeting at least ASP.NET Core 1.1. Next, using NuGet install the IdentityServer4 NuGet package.

Now that the IdentityServer4 NuGet package is installed open up the Startup class and add the following to the ConfigureServices function.

The above registers IdentityServer with ASP.NET Core as a service available via dependency injection using temporary and in-memory components as a stand in for testing. The Config class used here will be added a bit later.

Next, the Configure function should look like the following.

The above is a basic Configure function.  app.UseIdentityServer() is the only the only bit related to IdntityServer and it is adding it to the application’s pipeline.

The final part of this application is the Config class which is used to define the in memory test resources for this application. As you can see below it is defining both API resources and Clients. In the future theses, items would be pulled from a datastore.

API Application

For the API application, create an ASP.NET Core Web Application using the Web API template targeting at least ASP.NET Core 1.1. Next, using NuGet install the IdentityServer4.AccessTokenValidation NuGet package.

Ater the above NuGet package installed open up the Startup class. In the Configure function, the IdentityServer middleware needs to be added to the application pipeline before MVC using the app.UseIdentityServerAuthentication function. The following is the full Configure function.

Notice that the address of the of the authority must be specified (this will need to be the address the Identity Application is running on) as well as the ApiName matches the API Resource we added in the Config class of the Identity Application.

Next, in following the IdentityServer quickstart docs add a new IdentityController to the project. Just to be 100% clear this is just a test endpoint to show how to require authorization on a controller and isn’t something that is required to use IdentityServer. The controller has a single Get that returns the type and value of all the user’s claims.

The [Authorize] attribute on the class is the bit that requires calls to this endpoint to have authorization. Keep in mind that the same attribute can be left off the class level and added to specific functions if the whole controller doesn’t require authorization.

Adding the [Authorize] attribute means that the IdentityServer middleware we added in the Startup class will validate the token associated with the request to make sure it is from a trusted issues and that it is valid for this API.

Client Application

For the Client application, I deviated from the samples a bit. Instead of just creating a new MVC application I used JavaScriptServices to generate an Angular (4) application. If you want detail on how that is done you can check out this post (yes it says Angular 2, but the newest version of JavaScriptServices now outputs Angular 4 and the steps haven’t changed). An Angular application is my end goal and why I made this deviation from the samples.

After the Client application has been created use NuGet to add the IdentityModel package. This package is to make interacting with the Identity Application simpler.

For this first go instead of actually interacting with the Identity Application from Angular I will be using it from MVC instead. The detail of interaction from Angular will come in a later post. The IdentityController is what does the interaction with both the Identity Application and the API Application interactions in this version of the client application. The following is the full IdentityController class.

In the above, you can see the IdentityModel in action. Using the DiscoveryClient means the client application only needs to know about the root address of the Identity Application. TokenClient is being used to request a token from the Identity Application for the clientApp using the client secret which in this case is actually the word secret. Keep in mind in a real application secrets should be kept using the ASP.NET Core Secrets manager, see this related post. Also, take note that clientApp and secret are the values that were defined in the Config class of the Identity application.

The rest of the code is taking the token response and making a call to the API application with the response from both of those calls being stored in ViewData for display on the view associated with the controller.

The view is just an Index.cshtml file in the path Views/Identity. The following is the full view.

It isn’t pretty, but the whole point of this controller and view is just for verification that the three applications are properly communicating with each other.

URL Configuration

In this setup, it is important that the URL for the Identity Application and API Application be fixed so they can be accessed by the client. In a more production level application, these values would at a minimum need to be in configuration. The following is the setup used for this solution.

  • Identity Application – http://localhost:5000
  • API Application – http://localhost:5001
  • Client Application – http://localhost:5002

There are a couple of ways to configure test values. The first is to open the project properties and select the Debug tab and set the App URL.

The second option is to go to the Program class for each project and add a UseUrls to the WebHostBuilder like the following.

Wrapping up

After going through the above process I now have a much better understanding of how the very basic setup using Identity Server should work. I hope if you made this far you found some helpful bits.

There is a bit of strangeness using Visual Studio to try and launch all three applications and can result in an error message if multiple of the projects are run in debug mode. For the most part, this can be worked around by only debugging one application at a time. It is a bit annoying at the beginning stages, but once an applications gets past that point I imagian that the Identity Application won’t require much debugging.

If there are any questions please leave a comment and I would be happy to try and help. The finished code can be found here. This basic example will be expanded over time and all the related entries can be found in the IdentityServer category.

Identity Server: Introduction

In the SPA based sample applications, this blog has used so far user authentication has either been completely ignored in order to keep the examples simpler or the sites have used ASP.NET Core’s built in identity to encapsulate the whole SPA. In this post (or series of posts) I am going to share what I learn along the way of creating an Angular (2+) application that utilizes ASP.NET Core as its host/API/backend.

This post isn’t going to cover any code it is just going to be a lot of the information I gathered in the process of learning more about Identity Server.

Following are all the post in this series.

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

Identity Server

According to their docs IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core which enables Authentication as a Service, Single Sign-on, API Access Control and a Federation Gateway.

Obviously, that covers a lot of scenarios. The two that I am interested in are Authentication as a Service and the API Access Control which has driven my research which means that the other aspects of IdentityServer4 will not be included.

Official Samples

The IdentityServer GitHub account has a samples repo that contains a ton of examples. I have found the quickstart area of the repo to be the most helpful when starting out.

Based on all the quickstarts samples it looks like a typical setup involves a minimum of three projects. One for the API, one for the client and one for Identity Server. As you go through the samples the number of projects increase, but that is because of a wider range of scenarios that the sample is trying to cover.

References for learning

Damienbod has a whole series of blog posts related to IdentityServer4 and code to go along with it which can be found here. As a side note if you are interested in ASP.NET Core and you aren’t following damienbo you should be he has a ton of great content.

Blog posts
Videos

Identity Server Alternatives

Identity Server isn’t the only way to go there is a number of Software as a Service options that cover a lot of same scenarios. The following are some examples.

Auth0 – Check out the .NET Core related blogs by Jerrie Pelser
Stormpath
Amazon Cognito

Wrapping up

Obviously, I didn’t get a lot covered on how to actually do something with IdentityServer, but I wanted to share my starting point. This is an area I am going to continue digging it to and sharing information about as I learn more.

If you have any resources in this area please leave a comment below.