Reputation: 468
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
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