I'm working on an ASP.Net Core API project.
There are 2 controllers, controller A and B, I use Postman to pass my username and password to controller A action method, and it successfully returns a JWT. After I pass the JWT to controller B, I hope to get the username and role information of the credential which I had input into the controller A.
The code in controller B below shows the way I get the user info.
public async Task<ActionResult> Get()
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var role = await _userManager.GetRolesAsync(user);
return Ok(user);
}
But after I sent the JWT, I got null user.
Edit1:
ConfigureServices method in my Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "issuer",
ValidAudience = "audience",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("This is my super long security Key 123"))
};
});
services.AddDbContext<JWT_AuthContext>(option => option.UseSqlServer(Configuration.GetConnectionString("JWT_AuthContextConnection")));
}
IdentityHostingStartup.cs:
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<JWT_AuthContext>(options =>
options.UseSqlServer(
context.Configuration.GetConnectionString("JWT_AuthContextConnection")));
services.AddDefaultIdentity<JWT_AuthUser>()
.AddRoles<JWT_AuthRole>()
.AddEntityFrameworkStores<JWT_AuthContext>();
});
}
}
Controller Action for JWT generation (Controller A in the previous context):
[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private UserManager<JWT_AuthUser> _userManager;
public AuthController(UserManager<JWT_AuthUser> userManager)
{
_userManager = userManager;
}
[HttpPost("token")]
public async Task<ActionResult> GetToken()
{
var header = Request.Headers["Authorization"];
if(header.ToString().StartsWith("Basic"))
{
var loginInfo = header.ToString().Substring("Basic ".Length).Trim();
var userNameAndPassword = Encoding.UTF8.GetString(Convert.FromBase64String(loginInfo)); //username:password
var userName = userNameAndPassword.Split(":")[0];
var password = userNameAndPassword.Split(":")[1];
var user = await _userManager.FindByNameAsync(userName);
if (user != null && await _userManager.CheckPasswordAsync(user,password))
{
//security key
string securityKey = "This is my super long security Key 123";
//symmetric security key
var symmetricSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey));
//signing credentials
var signingCredentials = new SigningCredentials(symmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature);
//add claims
var claims = new List<Claim>();
//create token
var token = new JwtSecurityToken(
issuer: "issuer",
audience: "audience",
expires: DateTime.Now.AddHours(1),
claims: claims,
signingCredentials: signingCredentials
);
//return token
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
}
return Unauthorized();
}
Controller method for getting user info (Controller B in the previous context):
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private UserManager<JWT_AuthUser> _userManager;
public ValuesController(UserManager<JWT_AuthUser> userManager)
{
_userManager = userManager;
}
// GET api/values
[HttpGet]
public async Task<ActionResult> Get()
{
var user = await _userManager.GetUserAsync(HttpContext.User);
var role = await _userManager.GetRolesAsync(user);
return Ok(user);
}
}
Edit 2: Startup.cs Configure
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseMvc();
}