About this post

In this post, we will follow the steps from IdentityServer4 official documentation to create ASP.NET Core Identity connect. The official walkthrough is here athttp://docs.identityserver.io/en/release/quickstarts/0_overview.html. It is great but it skips some codes and detail setting. Here, I post my codes which follow that start documentation and I will give you more details about using IdentityServer4 to create the safe connection. To have a better understand, you need to read the official website for more details.

In this demo, we will create 3 projects : App Server, API Server and Client App. We could consider App Server as Facebook Server, API Server as a mobile game server, and the Client App as this mobile game.

In order let this game has a facebook login, the game user need to call the Facebook Server, typing into the user name and user password. After the Facebook passed the username and password, Facebook Server will send a token back to your local mobile game login page, then, the local game will use this token to talk with Facebook behalf of you to get your picture and facebook username.

2. Build Our Fake “Facebook” Identity Server

In the section, we will create a fake identity server using IdentityServer4.

Firstly, you need to create a .Net Core Web Application. In my Github, my project name is “IdentityServer4_Server”. After you created the project, let’s add the IdentityServer4Packages: IdentityServer4, IdentityServer4.AspNetIdentity,IdentityServer4.EntityFramework and IdentityServer4.EntityFramework.

Different from the official documentation to configure this project, we will create our fake user model and data resource. In this project, create a class Config.cs.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

using IdentityServer4.Models;

using System.Collections.Generic;

namespaceFacebookSiteLogin

{

publicclassConfig

{

publicstaticIEnumerable GetApiResources()

{

returnnewList

{

newApiResource("api1","My API")

};

}

publicstaticIEnumerable GetClients()

{

returnnewList

{

newClient

{

ClientId="client",

// no interactive user, use the clientid/secret for authentication

AllowedGrantTypes=GrantTypes.ClientCredentials,

// secret for authentication

ClientSecrets=

{

newSecret("secret".Sha256())

},

// scopes that client has access to

AllowedScopes={"api1"}

}

};

}

}

}

In this class, we fake the user information and data resource, which prepares our future usage.

Then, we modify our Program.cs File.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

using System;

using System.IO;

using Microsoft.AspNetCore.Hosting;

namespaceFacebookSiteLogin

{

publicclassProgram

{

publicstaticvoidMain(string[]args)

{

Console.Title="IdentityServer";

varhost=newWebHostBuilder()

.UseKestrel()

.UseUrls("http://localhost:5000")

.UseContentRoot(Directory.GetCurrentDirectory())

.UseIISIntegration()

.UseStartup()

.Build();

host.Run();

}

}

}

In here, we wish to user our port at 5000. However, in my machine site, it turns out to be some port number “65404”. After this setting, let’s try to run this project, check whether your localhost:XXXX is at 5000 or something else. You need to remember this port number for later use. Here, we consider this port number as Identity Port Number.

Next, let’s modify our Startup.cs file.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

using System;

using System.Collections.Generic;

using System.Linq;

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Logging;

namespaceFacebookSiteLogin

{

publicclassStartup

{

publicStartup(IHostingEnvironment env)

{

varbuilder=newConfigurationBuilder()

.SetBasePath(env.ContentRootPath)

.AddJsonFile("appsettings.json",optional:false,reloadOnChange:true)

.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional:true)

.AddEnvironmentVariables();

Configuration=builder.Build();

}

publicIConfigurationRootConfiguration{get;}

// This method gets called by the runtime. Use this method to add services to the container.

publicvoidConfigureServices(IServiceCollection services)

{

// Add framework services.

services.AddIdentityServer()

.AddTemporarySigningCredential()

.AddInMemoryApiResources(Config.GetApiResources())

.AddInMemoryClients(Config.GetClients());

services.AddMvc();

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

Now, we need to add a controller to offer API support. Right click the Controllers folder, create new API controller. Name it as IdentityController. Modify it as below.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

using Microsoft.AspNetCore.Http;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Authorization;

namespaceAPI_Server.Controllers

{

[Produces("application/json")]

[Authorize]

[Route("Identity")]

publicclassIdentityController:Controller

{

[HttpGet]

publicIActionResult Get()

{

returnnewJsonResult(fromcinUser.Claims selectnew{c.Type,c.Value});

}

}

}

Now, set the project debug order. Right click the solution in the “Solution Explorer”, click “Set Startup Projects…”. We need to order it as API_Server after the IdentityServer4_Server. Be careful, we need to choose Multiple startup projects.

Let’s start our debug. If everything is good, we will open two pages browser. In the second page, it is the new page from our API Server. It should be something like this.

4. Create Client Application

This is our last step to create the user client application, we can consider it as your local mobile game, which needs to login into Facebook.

First, the client app needs to talk with the Identity Server to get user token using your username and password. After getting the token, we can talk with the API server without limitation. We can consider the token as the key.

In here, to make things easy, we made our client application as a console app. In your solution, add a new .Net Core Console application.

We need to install IdentityModel into your new project. IdentityModel includes a client library to use with the discovery endpoint. This way you only need to know the base-address of IdentityServer – the actual endpoint addresses can be read from the metadata:

Let’s open the solution Setup Project Order, making this at the last one to run.

Now, Let’s Rock. Start your solution.

It is possible you may get this error.

This means the calling to your localhost:65404 fails. Let’s check the ports! When you get this error, let it stop there, please check the new two browser windows port numbers. They should be something like http://localhost:XXXXX/ and http://localhost:YYYYY/api/values. I am sure you will get these two window when you start your solution, since we have two .Core Web Application as the IdentityServer and the API Server.

Now, modify the port number in your Program.cs file.

XXXXX for :

1

vardiscoveryClient=newDiscoveryClient("http://localhost:61979");

YYYYY for :

1

varresponse=await client.GetAsync("http://localhost:58971/identity");

After modifying the codes, let’s run again. Now you could find something printed in the console.

If you get the internal error, it means you have the wrong port in your api server.

Go to your API_Server Startup.cs File, modify the port to your IdentityServer Port, since we need to set the api points to the IdentityServer.