Skip to content

Instantly share code, notes, and snippets.

@yehudamakarov
Last active May 3, 2019 02:16
Show Gist options
  • Save yehudamakarov/a72d2d33d4e7196db99a5a34b36e5ab5 to your computer and use it in GitHub Desktop.
Save yehudamakarov/a72d2d33d4e7196db99a5a34b36e5ab5 to your computer and use it in GitHub Desktop.
[JWT in .Net Core] basic JWT implementation with roles
public class AuthenticationBL : IAuthenticationBL
{
private readonly IAuthenticationRepository _authenticationRepository;
private readonly IConfiguration _configuration;
public AuthenticationBL(IAuthenticationRepository authenticationRepository, IConfiguration configuration)
{
_authenticationRepository = authenticationRepository;
_configuration = configuration;
}
public async Task<LoginResult> HandleAdminLogin(AdminLoginRequest adminLoginRequest)
{
var admin = await _authenticationRepository.GetAdmin(
adminLoginRequest.FirstName,
adminLoginRequest.LastName
);
if (admin == null) return new LoginResult() { Reason = LoginResult.ResultReason.UserNotFound };
if (adminLoginRequest.Password == null)
return new LoginResult() { Reason = LoginResult.ResultReason.PasswordNotProvided };
var correctPassword = ValidatePassword(adminLoginRequest.Password, admin.PasswordHash);
if (!correctPassword) return new LoginResult() { Reason = LoginResult.ResultReason.PasswordIncorrect };
var token = GenerateToken(admin);
return new LoginResult() { Token = token, Reason = LoginResult.ResultReason.SuccessfulLogin };
}
private string GenerateToken(User admin)
{
var signingKeyBytes = Convert.FromBase64String(_configuration["JWT_SIGNING_KEY"]);
var expiryDurationMinutes = int.Parse(_configuration["JWT_TOKEN_EXPIRY_DURATION_IN_MINUTES"]);
var tokenDescriptor = new SecurityTokenDescriptor()
{
Expires = DateTime.UtcNow.AddMinutes(expiryDurationMinutes),
Subject = new ClaimsIdentity(
new List<Claim>() { new Claim("role", "Administrator"), new Claim("userId", admin.Id) }
),
IssuedAt = DateTime.UtcNow,
NotBefore = DateTime.UtcNow,
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(signingKeyBytes),
SecurityAlgorithms.HmacSha256Signature
)
};
var tokenHandler = new JwtSecurityTokenHandler();
var tokenObject = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
return tokenHandler.WriteToken(tokenObject);
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
private IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(
options =>
{
var signingKeyBytes = Convert.FromBase64String(Configuration["JWT_SIGNING_KEY"]);
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(signingKeyBytes),
ValidateIssuer = false,
ValidateAudience = false,
};
}
);
services.AddScoped<IAuthenticationBL, AuthenticationBL>();
services.AddScoped<IAuthenticationRepository, AuthenticationRepository>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
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();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment