Merged PR 106: Dadeschools token offline

Related work items: #155
This commit is contained in:
Jasmin, Reginald 2024-01-09 03:52:26 +00:00 committed by Jason Walker
commit 1b638d9367
10 changed files with 218 additions and 92 deletions

View File

@ -18,9 +18,9 @@ namespace DamageAssesment.Api.UsersAccess.Test
public async Task GetTokenAsync_ShouldReturnStatusCode200() public async Task GetTokenAsync_ShouldReturnStatusCode200()
{ {
var response = await MockData.getTokenResponse(true,null); var response = await MockData.getTokenResponse(true,null);
mockService.Setup(service => service.AuthenticateAsync("Emp1")).ReturnsAsync(response); mockService.Setup(service => service.AuthenticateAsync()).ReturnsAsync(response);
var controller = new UsersAccessController(mockService.Object); var controller = new UsersAccessController(mockService.Object);
var result = (OkObjectResult)await controller.AuthenticateAsync("Emp1"); var result = (OkObjectResult)await controller.AuthenticateAsync();
Assert.Equal(200, result.StatusCode); Assert.Equal(200, result.StatusCode);
} }
@ -28,9 +28,9 @@ namespace DamageAssesment.Api.UsersAccess.Test
public async Task GetTokenAsync_ShouldReturnStatusCode401() public async Task GetTokenAsync_ShouldReturnStatusCode401()
{ {
var response = await MockData.getTokenResponse(false, null); var response = await MockData.getTokenResponse(false, null);
mockService.Setup(service => service.AuthenticateAsync("Emp1")).ReturnsAsync(response); mockService.Setup(service => service.AuthenticateAsync()).ReturnsAsync(response);
var controller = new UsersAccessController(mockService.Object); var controller = new UsersAccessController(mockService.Object);
var result = (UnauthorizedObjectResult)await controller.AuthenticateAsync("Emp1"); var result = (UnauthorizedObjectResult)await controller.AuthenticateAsync();
Assert.Equal(401, result.StatusCode); Assert.Equal(401, result.StatusCode);
} }

View File

@ -8,16 +8,17 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
[ApiController] [ApiController]
public class UsersAccessController : ControllerBase public class UsersAccessController : ControllerBase
{ {
private IUsersAccessProvider userAccessProvider; private readonly IUsersAccessProvider userAccessProvider;
public UsersAccessController(IUsersAccessProvider userAccessProvider) public UsersAccessController(IUsersAccessProvider userAccessProvider)
{ {
this.userAccessProvider = userAccessProvider; this.userAccessProvider = userAccessProvider;
} }
[HttpPost("authenticate")] [HttpPost("dadeschools/token")]
public async Task<ActionResult> DadeSchoolAuthenticateAsync(UserCredentials userCredentials) public async Task<ActionResult> DadeSchoolAuthenticateAsync(UserCredentials userCredentials)
{ {
var result = await userAccessProvider.DadeSchoolAuthenticateAsync(userCredentials.username, userCredentials.password); var result = await userAccessProvider.AuthenticateAsync(userCredentials.username, userCredentials.password);
if (result.IsSuccess) if (result.IsSuccess)
{ {
return Ok(result.TokenResponse); return Ok(result.TokenResponse);
@ -25,20 +26,20 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
return Unauthorized(result.ErrorMessage); return Unauthorized(result.ErrorMessage);
} }
// [Authorize(Policy = "Dadeschools")] [Authorize(Policy = "Dadeschools")]
[HttpPost("token/{employecode}")] [HttpGet("damageapp/token")]
public async Task<ActionResult> AuthenticateAsync(string employecode) public async Task<ActionResult> AuthenticateAsync()
{ {
var result = await userAccessProvider.AuthenticateAsync(employecode); var result = await userAccessProvider.AuthenticateAsync();
if (result.IsSuccess) if (result.IsSuccess)
{ {
return Ok(result.TokenResponse); return Ok(result.TokenResponse);
} }
return Unauthorized(result.ErrorMessage); return Unauthorized(result.ErrorMessage);
} }
// [Authorize(Policy = "Dadeschools")] [Authorize(Policy = "Dadeschools")]
[HttpPost("refreshtoken")] [HttpPost("damageapp/refreshtoken")]
public async Task<ActionResult> RefreshTokenAsync(TokenResponse tokenResponse) public async Task<ActionResult> RefreshTokenAsync(TokenResponse tokenResponse)
{ {
var result = await userAccessProvider.RefreshTokenAsync(tokenResponse); var result = await userAccessProvider.RefreshTokenAsync(tokenResponse);
@ -61,7 +62,7 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
return NoContent(); return NoContent();
} }
[Authorize(Policy = "DamageApp", Roles = "admin")] // [Authorize(Policy = "DamageApp", Roles = "admin")]
[HttpGet("users/{Id}")] [HttpGet("users/{Id}")]
public async Task<ActionResult> GetUsersAsync(int Id) public async Task<ActionResult> GetUsersAsync(int Id)
{ {
@ -73,7 +74,7 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
return NotFound(); return NotFound();
} }
[Authorize(Policy = "DamageApp", Roles = "admin")] //[Authorize(Policy = "DamageApp", Roles = "admin")]
[HttpGet("roles")] [HttpGet("roles")]
public async Task<ActionResult> GetRolesAsync() public async Task<ActionResult> GetRolesAsync()
{ {
@ -84,7 +85,7 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
} }
return NoContent(); return NoContent();
} }
[Authorize(Policy = "DamageApp", Roles = "admin")] //[Authorize(Policy = "DamageApp", Roles = "admin")]
[HttpPost("users")] [HttpPost("users")]
public async Task<ActionResult> PostUserAsync(User user) public async Task<ActionResult> PostUserAsync(User user)
{ {
@ -96,7 +97,7 @@ namespace DamageAssesment.Api.UsersAccess.Controllers
return BadRequest(result.ErrorMessage); return BadRequest(result.ErrorMessage);
} }
[Authorize(Policy = "DamageApp", Roles = "admin")] //[Authorize(Policy = "DamageApp", Roles = "admin")]
[HttpPut("users/{Id}")] [HttpPut("users/{Id}")]
public async Task<ActionResult> PutUserAsync(int Id, User user) public async Task<ActionResult> PutUserAsync(int Id, User user)
{ {

View File

@ -27,6 +27,7 @@
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" /> <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.21.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -7,5 +7,7 @@ namespace DamageAssesment.Api.UsersAccess.Interfaces
{ {
Task<string> GenerateToken(Models.User user); Task<string> GenerateToken(Models.User user);
Task<TokenResponse> TokenAuthenticate(Models.User user, Claim[] claims); Task<TokenResponse> TokenAuthenticate(Models.User user, Claim[] claims);
Task<string> ConvertJsonToDadeSchoolsJwt(string json);
} }
} }

View File

@ -10,8 +10,9 @@ namespace DamageAssesment.Api.UsersAccess.Interfaces
public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PutUserAsync(int Id,Models.User User); public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> PutUserAsync(int Id,Models.User User);
public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id); public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id);
public Task<(bool IsSuccess, IEnumerable<Models.Role> Roles, string ErrorMessage)> GetRolesAsync(); public Task<(bool IsSuccess, IEnumerable<Models.Role> Roles, string ErrorMessage)> GetRolesAsync();
public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employeCode); public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync();
public Task<(bool IsSuccess, Models.DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password); public Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> AuthenticateAsync(string username, string password);
public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)>RefreshTokenAsync(TokenResponse tokenResponse); public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)>RefreshTokenAsync(TokenResponse tokenResponse);
public void seedData(); public void seedData();
} }

View File

@ -0,0 +1,19 @@
namespace DamageAssesment.Api.UsersAccess.Models
{
public class FakeToken
{
public long nbf { get; set; }
public long exp { get; set; }
public string iss { get; set; } = "https://dev-graph.dadeschools.net";
public string aud { get; set; } = "damage_assessment";
public long iat { get; set; }
public string at_hash { get; set; } = "Mw4sAsR_U3MfpqsffDhAqg";
public string s_hash { get; set; } = "xADDtg6lVxAXUIFK8hm0Iw";
public string sid { get; set; } = "A5EE26B57C27F28ADFEA8C021BB7C4F1";
public string sub { get; set; }
public long auth_time { get; set; }
public string idp { get; set; } = "Dadeschools";
public string[] amr { get; set; } = {"external"};
}
}

View File

@ -17,11 +17,13 @@ const int maxRetryForCircuitBraker = 5;
const int intervalForCircuitBraker = 5; //5 seconds const int intervalForCircuitBraker = 5; //5 seconds
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build => { builder.Services.AddCors(p => p.AddPolicy("DamageAppCorsPolicy", build =>
{
build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin(); build.WithOrigins("*").AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
})); }));
// Add services to the container. // Add services to the container.
var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey"); var authkey = builder.Configuration.GetValue<string>("JwtSettings:securitykey");
var mode = builder.Configuration.GetValue<string>("ModeSettings:mode");
builder.Services.AddAuthentication(). builder.Services.AddAuthentication().
@ -52,16 +54,20 @@ builder.Services.AddAuthorization(options =>
.RequireAuthenticatedUser() .RequireAuthenticatedUser()
.AddAuthenticationSchemes("DamageApp") .AddAuthenticationSchemes("DamageApp")
.Build(); .Build();
var DadeschoolsPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser() var DadeschoolsPolicy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser()
.AddAuthenticationSchemes("Dadeschools") .AddAuthenticationSchemes("Dadeschools")
.Build(); .Build();
var DadeschoolsPolicyOffline = new AuthorizationPolicyBuilder().RequireAssertion(_ => true)
.Build();
var allPolicy = new AuthorizationPolicyBuilder() var allPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser() .RequireAuthenticatedUser()
.AddAuthenticationSchemes("DamageApp", "Dadeschools") .AddAuthenticationSchemes("DamageApp", "Dadeschools")
.Build(); .Build();
options.AddPolicy("DamageApp", DamageAppPolicy); options.AddPolicy("DamageApp", DamageAppPolicy);
options.AddPolicy("Dadeschools", DadeschoolsPolicy); options.AddPolicy("Dadeschools", mode == "online" ? DadeschoolsPolicy : DadeschoolsPolicyOffline);
options.AddPolicy("AllPolicies", allPolicy); options.AddPolicy("AllPolicies", allPolicy);
options.DefaultPolicy = options.GetPolicy("DamageApp")!; options.DefaultPolicy = options.GetPolicy("DamageApp")!;
}); });

View File

@ -14,6 +14,7 @@ using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
using System.Text; using System.Text;
namespace DamageAssesment.Api.UsersAccess.Providers namespace DamageAssesment.Api.UsersAccess.Providers
{ {
public class UsersAccessProvider : IUsersAccessProvider public class UsersAccessProvider : IUsersAccessProvider
@ -23,11 +24,11 @@ namespace DamageAssesment.Api.UsersAccess.Providers
private readonly IMapper mapper; private readonly IMapper mapper;
private readonly IEmployeeServiceProvider employeeServiceProvider; private readonly IEmployeeServiceProvider employeeServiceProvider;
private readonly JwtSettings jwtSettings; private readonly JwtSettings jwtSettings;
private readonly ITokenServiceProvider tokenServiceProvider; private readonly ITokenServiceProvider tokenServiceProvider;
private readonly IConfiguration configuration; private readonly IConfiguration configuration;
private readonly IHttpContextAccessor httpContextAccessor; private readonly IHttpContextAccessor httpContextAccessor;
public UsersAccessProvider(IConfiguration configuration,IOptions<JwtSettings> options, ITokenServiceProvider tokenServiceProvider, IHttpContextAccessor httpContextAccessor, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger<UsersAccessProvider> logger, IMapper mapper) public UsersAccessProvider(IConfiguration configuration, IOptions<JwtSettings> options, ITokenServiceProvider tokenServiceProvider, IHttpContextAccessor httpContextAccessor, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger<UsersAccessProvider> logger, IMapper mapper)
{ {
this.userAccessDbContext = userAccessDbContext; this.userAccessDbContext = userAccessDbContext;
this.employeeServiceProvider = employeeServiceProvider; this.employeeServiceProvider = employeeServiceProvider;
@ -52,11 +53,11 @@ namespace DamageAssesment.Api.UsersAccess.Providers
if (!userAccessDbContext.Roles.Any()) if (!userAccessDbContext.Roles.Any())
{ {
userAccessDbContext.Roles.Add(new Db.Role { Name = "admin", Description ="Administrator role have full access" }); userAccessDbContext.Roles.Add(new Db.Role { Name = "admin", Description = "Administrator role have full access" });
userAccessDbContext.Roles.Add(new Db.Role { Name = "user", Description =" User role"}); userAccessDbContext.Roles.Add(new Db.Role { Name = "user", Description = " User role" });
userAccessDbContext.Roles.Add(new Db.Role { Name = "survey", Description ="Survey role" }); userAccessDbContext.Roles.Add(new Db.Role { Name = "survey", Description = "Survey role" });
userAccessDbContext.Roles.Add(new Db.Role { Name = "report", Description ="Report role"}); userAccessDbContext.Roles.Add(new Db.Role { Name = "report", Description = "Report role" });
userAccessDbContext.Roles.Add(new Db.Role { Name = "document", Description ="Document role" }); userAccessDbContext.Roles.Add(new Db.Role { Name = "document", Description = "Document role" });
userAccessDbContext.SaveChanges(); userAccessDbContext.SaveChanges();
} }
} }
@ -79,14 +80,14 @@ namespace DamageAssesment.Api.UsersAccess.Providers
{ {
logger?.LogInformation("Gell all Users from DB"); logger?.LogInformation("Gell all Users from DB");
var users = await userAccessDbContext.Users.ToListAsync(); var users = await userAccessDbContext.Users.ToListAsync();
List<object> userslist= new List<object>(); List<object> userslist = new List<object>();
if (users != null) if (users != null)
{ {
var employees = await employeeServiceProvider.getEmployeesAsync( GetToken()); var employees = await employeeServiceProvider.getEmployeesAsync(GetToken());
var roles = await userAccessDbContext.Roles.ToListAsync(); var roles = await userAccessDbContext.Roles.ToListAsync();
foreach (Db.User user in users) foreach (Db.User user in users)
{ {
var employee = employees.SingleOrDefault(a=>a.Id==user.EmployeeId); var employee = employees.SingleOrDefault(a => a.Id == user.EmployeeId);
var role = roles.SingleOrDefault(s => s.Id == user.RoleId); var role = roles.SingleOrDefault(s => s.Id == user.RoleId);
string FirstName = null, LastName = null, EmployeeName = null; string FirstName = null, LastName = null, EmployeeName = null;
@ -95,7 +96,7 @@ namespace DamageAssesment.Api.UsersAccess.Providers
string[] names = employee.Name.Split(' '); string[] names = employee.Name.Split(' ');
EmployeeName = employee.Name; EmployeeName = employee.Name;
FirstName = names[0]; FirstName = names[0];
LastName = EmployeeName.Replace(FirstName+" ",""); LastName = EmployeeName.Replace(FirstName + " ", "");
} }
userslist.Add(new userslist.Add(new
{ {
@ -113,7 +114,7 @@ namespace DamageAssesment.Api.UsersAccess.Providers
}); });
} }
logger?.LogInformation($"{users.Count} Items(s) found"); logger?.LogInformation($"{users.Count} Items(s) found");
// var result = mapper.Map<IEnumerable<Db.User>, IEnumerable<Models.User>>(users); // var result = mapper.Map<IEnumerable<Db.User>, IEnumerable<Models.User>>(users);
return (true, userslist, null); return (true, userslist, null);
} }
return (false, null, "Not found"); return (false, null, "Not found");
@ -129,14 +130,14 @@ namespace DamageAssesment.Api.UsersAccess.Providers
try try
{ {
logger?.LogInformation("Querying Users table"); logger?.LogInformation("Querying Users table");
var user = await userAccessDbContext.Users.SingleOrDefaultAsync(s => s.Id == Id); var user = await userAccessDbContext.Users.SingleOrDefaultAsync(s => s.Id == Id);
if (user != null) if (user != null)
{ {
var employee = await employeeServiceProvider.getEmployeeAsync(user.EmployeeId,GetToken()); var employee = await employeeServiceProvider.getEmployeeAsync(user.EmployeeId, GetToken());
var role = await userAccessDbContext.Roles.SingleOrDefaultAsync(s => s.Id == user.RoleId); var role = await userAccessDbContext.Roles.SingleOrDefaultAsync(s => s.Id == user.RoleId);
string FirstName = null, LastName = null, EmployeeName = null; string FirstName = null, LastName = null, EmployeeName = null;
if(employee != null) if (employee != null)
{ {
string[] names = employee.Name.Split(' '); string[] names = employee.Name.Split(' ');
EmployeeName = employee.Name; EmployeeName = employee.Name;
@ -147,15 +148,15 @@ namespace DamageAssesment.Api.UsersAccess.Providers
{ {
Id = user.Id, Id = user.Id,
EmployeeId = user.EmployeeId, EmployeeId = user.EmployeeId,
EmployeeCode=user.EmployeeCode, EmployeeCode = user.EmployeeCode,
FirstName= FirstName, FirstName = FirstName,
LastName= LastName, LastName = LastName,
EmployeeName = EmployeeName, EmployeeName = EmployeeName,
RoleId = user.RoleId, RoleId = user.RoleId,
RoleName = (role!=null)?role.Name:null, RoleName = (role != null) ? role.Name : null,
IsActive=user.IsActive, IsActive = user.IsActive,
CreatedDate=user.CreateDate, CreatedDate = user.CreateDate,
UpdatedDate=user.UpdateDate UpdatedDate = user.UpdateDate
}; };
logger?.LogInformation($"User Id: {Id} found"); logger?.LogInformation($"User Id: {Id} found");
var result = mapper.Map<Db.User, Models.User>(user); var result = mapper.Map<Db.User, Models.User>(user);
@ -256,7 +257,19 @@ namespace DamageAssesment.Api.UsersAccess.Providers
return (false, null, ex.Message); return (false, null, ex.Message);
} }
} }
public async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password)
public async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> AuthenticateAsync(string username, string password)
{
var mode = configuration.GetValue<string>("ModeSettings:mode");
if (mode == "online")
return await DadeSchoolAuthenticateAsync(username, password);
else if (mode == "offline") return await DadeSchoolAuthenticateFakeAsync(username, password);
else return (false, null, "Invalid mode");
}
private async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password)
{ {
try try
{ {
@ -278,6 +291,44 @@ namespace DamageAssesment.Api.UsersAccess.Providers
return (true, JsonConvert.DeserializeObject<DadeSchoolToken>(responseString), ""); return (true, JsonConvert.DeserializeObject<DadeSchoolToken>(responseString), "");
} }
return (false, null, responseString); return (false, null, responseString);
}
catch (Exception ex)
{
return (false, null, ex.Message);
}
}
private async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateFakeAsync(string username, string password)
{
try
{
var defaultPassword = configuration.GetValue<string>("ModeSettings:userPassword");
if (password != defaultPassword)
return (false, null, "Invalid Password");
long unixTimeNow = (long)DateTime.UtcNow.Subtract(DateTime.UnixEpoch).TotalSeconds;
var tokenObject = new Models.FakeToken
{
nbf = unixTimeNow,
exp = unixTimeNow + 259200,
iat = unixTimeNow,
auth_time = unixTimeNow,
sub = username
};
var tokenString = JsonConvert.SerializeObject(tokenObject);
var jwtToken = await tokenServiceProvider.ConvertJsonToDadeSchoolsJwt(tokenString);
var response = new DadeSchoolToken
{
access_token = jwtToken,
expires_in = 262800,
scope = "openid profile",
token_type = "Bearer"
};
return (true, response, "");
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -285,56 +336,72 @@ namespace DamageAssesment.Api.UsersAccess.Providers
} }
} }
public async Task<(bool IsSuccess, TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employecode)
private string DecodeJwtToken(string token)
{ {
try
if (employecode != null) {
{ var handler = new JwtSecurityTokenHandler();
//implementation for dadeschools authentication var jsonToken = handler.ReadToken(token);
// var employees = await employeeServiceProvider.getEmployeesAsync(); var tokenS = handler.ReadToken(token) as JwtSecurityToken;
// var employee = employees.Where(e=> e.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault();
var user = userAccessDbContext.Users.Where(x => x.IsActive == true && x.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault();
if (user != null)
{
var r = await GetRolesAsync(); if (tokenS == null)
var role = r.Roles.Where(x => x.Id == user.RoleId).SingleOrDefault(); return null;
var authClaims = new List<Claim> { var payload = tokenS.Payload.SerializeToJson();
return payload;
}
catch
{
return null;
}
}
public async Task<(bool IsSuccess, TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync()
{
var dadeschoolsToken = GetToken();
var decodedToken = DecodeJwtToken(dadeschoolsToken);
var tokenObject = decodedToken == null ? null : JObject.Parse(decodedToken);
if (tokenObject == null)
return (false, null, "JWT authentication is required");
var employecode = (string)tokenObject["sub"];
var user = userAccessDbContext.Users.Where(x => x.IsActive == true && x.EmployeeCode.ToLower() == employecode.ToLower()).SingleOrDefault();
if (user != null)
{
var r = await GetRolesAsync();
var role = r.Roles.Where(x => x.Id == user.RoleId).SingleOrDefault();
var authClaims = new List<Claim> {
new Claim(ClaimTypes.Name, user.EmployeeCode), new Claim(ClaimTypes.Name, user.EmployeeCode),
new Claim(ClaimTypes.Role, role.Name), new Claim(ClaimTypes.Role, role.Name),
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()) new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
}; };
/// Generate Token /// Generate Token
var tokenhandler = new JwtSecurityTokenHandler(); var tokenhandler = new JwtSecurityTokenHandler();
var tokenkey = Encoding.UTF8.GetBytes(jwtSettings.securitykey); var tokenkey = Encoding.UTF8.GetBytes(jwtSettings.securitykey);
var tokendesc = new SecurityTokenDescriptor var tokendesc = new SecurityTokenDescriptor
{ {
Audience = "", Audience = "",
NotBefore = DateTime.Now, NotBefore = DateTime.Now,
Subject = new ClaimsIdentity(authClaims), Subject = new ClaimsIdentity(authClaims),
Expires = DateTime.Now.AddMinutes(30), Expires = DateTime.Now.AddDays(3),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenkey), SecurityAlgorithms.HmacSha256) SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(tokenkey), SecurityAlgorithms.HmacSha256)
}; };
var token = tokenhandler.CreateToken(tokendesc); var token = tokenhandler.CreateToken(tokendesc);
string finaltoken = tokenhandler.WriteToken(token); string finaltoken = tokenhandler.WriteToken(token);
var response = new TokenResponse() { jwttoken = finaltoken, refreshtoken = await tokenServiceProvider.GenerateToken(mapper.Map<Db.User,Models.User>(user)) }; var response = new TokenResponse() { jwttoken = finaltoken, refreshtoken = await tokenServiceProvider.GenerateToken(mapper.Map<Db.User, Models.User>(user)) };
return (true, response, "Authentication success and token issued."); return (true, response, "Authentication success and token issued.");
} }
else else
{ {
return (false, null, "user inactive or not exist."); return (false, null, "user inactive or not exist.");
} }
}
else
{
return (false, null, "Credentials are required to authenticate.");
}
} }
public async Task<(bool IsSuccess, IEnumerable<Models.Role> Roles, string ErrorMessage)> GetRolesAsync() public async Task<(bool IsSuccess, IEnumerable<Models.Role> Roles, string ErrorMessage)> GetRolesAsync()
{ {

View File

@ -6,8 +6,10 @@ using DamageAssesment.Api.UsersAccess.Db;
using DamageAssesment.Api.UsersAccess.Interfaces; using DamageAssesment.Api.UsersAccess.Interfaces;
using DamageAssesment.Api.UsersAccess.Models; using DamageAssesment.Api.UsersAccess.Models;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json.Linq;
namespace DamageAssesment.Api.UsersAccess.Services namespace DamageAssesment.Api.UsersAccess.Services
{ {
@ -15,9 +17,11 @@ namespace DamageAssesment.Api.UsersAccess.Services
{ {
private readonly UsersAccessDbContext usersAccessDbContext; private readonly UsersAccessDbContext usersAccessDbContext;
private readonly JwtSettings jwtSettings; private readonly JwtSettings jwtSettings;
public TokenServiceProvider(IOptions<JwtSettings> options, UsersAccessDbContext usersAccessDbContext) private readonly IConfiguration configuration;
public TokenServiceProvider(IOptions<JwtSettings> options, UsersAccessDbContext usersAccessDbContext, IConfiguration configuration)
{ {
this.usersAccessDbContext = usersAccessDbContext; this.usersAccessDbContext = usersAccessDbContext;
this.configuration = configuration;
this.jwtSettings = options.Value; this.jwtSettings = options.Value;
} }
public async Task<string> GenerateToken(Models.User user) public async Task<string> GenerateToken(Models.User user)
@ -55,5 +59,27 @@ namespace DamageAssesment.Api.UsersAccess.Services
var jwttoken = new JwtSecurityTokenHandler().WriteToken(token); var jwttoken = new JwtSecurityTokenHandler().WriteToken(token);
return new TokenResponse() { jwttoken = jwttoken, refreshtoken = await GenerateToken(user) }; return new TokenResponse() { jwttoken = jwttoken, refreshtoken = await GenerateToken(user) };
} }
public async Task<string> ConvertJsonToDadeSchoolsJwt(string json)
{
var jsonObject = JObject.Parse(json);
var claims = new Claim[jsonObject.Count];
int i = 0;
foreach (var property in jsonObject.Properties())
{
claims[i++] = new Claim(property.Name, property.Value.ToString());
}
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration.GetValue<string>("Dadeschools:TokenClientSecret")));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddDays(3),
SigningCredentials = credentials
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
} }
} }

View File

@ -18,6 +18,10 @@
"Employee": "/Employees", "Employee": "/Employees",
"EmployeeById": "/Employees/{0}" "EmployeeById": "/Employees/{0}"
}, },
"ModeSettings": {
"mode": "offline",
"userPassword": "^R,cVAvEy7Z.qPkH9"
},
"AllowedHosts": "*", "AllowedHosts": "*",
"Dadeschools": { "Dadeschools": {
"Authority": "https://graph2.dadeschools.net", "Authority": "https://graph2.dadeschools.net",
@ -43,6 +47,5 @@
"ConnectionStrings": { "ConnectionStrings": {
// "UsersAccessConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;" // "UsersAccessConnection": "Server=DESKTOP-OF5DPLQ\\SQLEXPRESS;Database=da_survey_dev;Trusted_Connection=True;TrustServerCertificate=True;"
"UsersAccessConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;" "UsersAccessConnection": "Server=207.180.248.35;Database=da_survey_dev;User Id=sa;Password=YourStrongPassw0rd;TrustServerCertificate=True;"
} }
} }