I have the following useful load in a token generated with JWT
{ "sub": "flamelsoft@gmail.com", "jti": "0bca1034-f3ce-4f72-bd91-65c1a61924c4", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Administrator", "exp": 1509480891, "iss": "http://localhost:40528", "aud": "http://localhost:40528" }
with this code Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DBContextSCM>(options =>
options.UseMySql(Configuration.GetConnectionString("DefaultConnection"), b =>
b.MigrationsAssembly("FlamelsoftSCM")));
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<DBContextSCM>()
.AddDefaultTokenProviders();
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddAuthentication()
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
};
});
services.AddMvc();
}
AccountController.cs
[HttpPost]
[Authorize(Roles="Administrator")]
public async Task<IActionResult> Register([FromBody]RegisterModel model)
{
try
{
var user = new User { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var role = await _roleManager.FindByIdAsync(model.Role);
result = await _userManager.AddToRoleAsync(user, role.Name);
if (result.Succeeded)
return View(model);
}
return BadRequest($"Error: Could not create user");
}
catch (Exception ex)
{
return BadRequest($"Error: {ex.Message}");
}
}
user.service.ts
export class UserService {
constructor(private http: Http, private config: AppConfig, private currentUser: User) { }
create(user: User) {
return this.http.post(this.config.apiUrl + 'Account/Register', user, this.jwt());
}
private jwt() {
const userJson = localStorage.getItem('currentUser');
this.currentUser = userJson !== null ? JSON.parse(userJson) : new User();
if (this.currentUser && this.currentUser.token) {
let headers = new Headers({ 'Authorization': 'Bearer ' + this.currentUser.token });
return new RequestOptions({ headers: headers });
}
}}
The problem is that the validation of the role does not work, the request arrives at the controller and returns a code 200 in the header, but never enters the class. When I remove the [Authorize (Roles = "Administrator")] it enters correctly my code. Is there something badly defined? Or what would be the alternative to define an authorization through roles.
[Authorize (Roles = "Administrator")]
by[Authorize]
? This will enforce that the user be successfully authenticated but not require they're part of theAdministrator
role. Depending on the result we'll decide where to look next. - Mickaël DerrieyClaimsPrincipal
that is generated from the token.JwtBearerOptions
exposes anEvents
property that allows you to hook some logic at different stages of the authentication process. TheTokenValidated
method will be called after authentication is successful as you can see here. Inspect the claims of the generated principal and give us the result. - Mickaël Derriey[Authorize(AuthenticationSchemes = "Bearer", Roles = "Administrator")]
- Team Flamelsoft