Razgort
Razgort

Reputation: 468

Share Jwt token between two asp core api

I'm having trouble here. I'm trying to build a second asp core api that will share a jwt token created buy my main aspcore api aka : authorization server. But i can't get it to work.

The idea is that my angular client will get a token from my main api (authorization server) and send this same token to get data from an other api which will have to check with the auth server i guess if the token is valid.

I think this is somewhere in the configure otpion :

            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Jwt:Issuer"],
                    ValidAudience = Configuration["Jwt:Audience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])),
                           // Ensure the token audience matches our audience value (default true):
                    ValidateAudience = true,

                };

And i have in my config file :

  "Jwt": {
    "Key": "METAPRODUCTIQUE2904",
    "Audience": "http://localhost:52771/",
    "Issuer": "http://localhost:52771",
  },

Then main app run on port 52771 for test and my current secondary app on port 52772 But i think i did something wrong but can't figure what I'd greatly appreciate some ideas from you guys

Upvotes: 3

Views: 4027

Answers (1)

AminSojoudi
AminSojoudi

Reputation: 2016

First, Let's find out how it's going to work.

1) user ---------------------(Get Token) ---------------------> AuthServer
2) AuthServer -----------------(Token)------------------------> user
3) user ----------(Request with Token as auth header)---------> OtherServers

In Step 2 the AuthServer checks the user permissions and creates a package of data that contains user info, permissions, and other stuff, then it encrypts that with the key you provided to a base64 string which we call it Token.

We have the key in other servers too. When a request reaches to them they first try to decrypt it with the key. And if everything goes right, Now the other server has the user info and permissions and other stuff.

So the AuthServer does not need to be connected to other servers and they can work with each other.

In the startup class of both Services you should have the following code :

 public void ConfigureServices(IServiceCollection services)
        {
            ...
            // JWT
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes("MySpecialKey")),
                    ValidIssuer = "MainServer",
                    ValidAudience = "Sample",
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
            ...
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            ...
            app.UseAuthentication();
            ...
        }

And in one of the services of authorization server you should implement a method to generate tokens for registered users :

public async Task<string> GenToken()
        {
            // check if the user has the required permissions
            ....

            // authentication successful so generate jwt token
            var tokenHandler = new JwtSecurityTokenHandler();
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, "Username"),
                }),
                Expires = DateTime.UtcNow.AddDays(1),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.ASCII
                    .GetBytes("MySpecialKey")), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);

            return tokenString;
        }

Now you can use the [Authorize] attribute on top of controllers or APIs.

Each request to [Authorize] controllers or APIs should contain a header with key Authorization and value of bearer USERTOKEN

Upvotes: 4

Related Questions