Reputation: 498
I have An API project that uses JWT authentication and issues a token on Login.
I'm using ASP.NET core MVC project as a client
On Successful login in the client application, a JWT token is returned, Now that I have the JWT token,
How can I access User.Identity in my client application?
What do I need to do to get and use the User Identity throughout the application?
How can I Manage Authorization in the Client Application?
API project
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("JwtSettings");
services.Configure<JwtSettings>(appSettingsSection);
// configure jwt authentication
var appSettings = appSettingsSection.Get<JwtSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
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(key),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = appSettings.Issuer,
ValidAudience = appSettings.Audience,
ClockSkew = TimeSpan.Zero
};
x.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
Login Endpoint
[HttpPost]
public ActionResult Login([FromBody] LoginViewModel user)
{
if (user == null)
{
return BadRequest("Invalid client request");
}
if (user.Email == "[email protected]")
{
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: appSettings.Issuer,
audience: appSettings.Audience,
claims: new List<Claim>(),
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(30),
signingCredentials: signinCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
return Ok(new GenericResponse<string> { Data = tokenString, Message = null, Success = true });
}
else
{
return Unauthorized(new GenericResponse<string> { Data = null, Message = "Unauthorized", Success = false });
}
}
Upvotes: 1
Views: 2487
Reputation: 498
To make Brando's answer work, I ended up doing this.
app.Use(async (context, next) =>
{
string token = context.Session.GetString(config.AccessTokenName);
if (!string.IsNullOrEmpty(token))
{
var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(token);
var userIdentity = new ClaimsIdentity(jwttoken.Claims);
context.User = new ClaimsPrincipal(userIdentity);
}
await next();
});
Upvotes: 1
Reputation: 27962
As far as I know, if you want to create a custom ClaimsPrincipal, I suggest you could try to use custom middleware in your client asp.net core application.
You could get the token from Request.Headers or Session(Based on your own logic).
Then you could use JwtSecurityTokenHandler().ReadJwtToken to read the token.
More details, you could refer to below codes:
Add app.use codes into the startup.cs Configure method.Notice: you should put it before the use.endpoint.
app.UseRouting();
app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints
app.UseCookiePolicy();
app.UseSession();
app.Use(async (context, next) =>
{
// you could get from token or get from session.
string token = context.Request.Headers["Authorization"];
if (!string.IsNullOrEmpty(token))
{
var tok = token.Replace("Bearer ", "");
var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(tok);
var claims = new List<Claim> { /* add claims */ };
var userIdentity = new ClaimsIdentity(claims, ClaimTypes.Name);
context.User = new ClaimsPrincipal(userIdentity);
}
await next();
});
Then you could directly get the token username in the client action:
var user = User.Identity.Name;
Result:
Upvotes: 3