Na most van kész a 2 faktoros authentikáció ! :)

This commit is contained in:
2025-04-10 23:32:36 +02:00
parent aca0a86a6a
commit 9d107e8c0b
6 changed files with 218 additions and 25 deletions
@@ -183,7 +183,7 @@ namespace WorkFlowCheck.API.Controllers
try try
{ {
var response = await _userService.Authenticate2F1(userSimpleDTO.UserName, userSimpleDTO.Password); var response = await _userService.Authenticate2F1(userSimpleDTO.UserName, userSimpleDTO.Password);
if (response != null) if (!string.IsNullOrEmpty(response))
{ {
retVal.IsSuccess = true; retVal.IsSuccess = true;
retVal.Data = response; retVal.Data = response;
@@ -222,9 +222,9 @@ namespace WorkFlowCheck.API.Controllers
} }
try try
{ {
var userDTO_Response = await _userService.Authenticate2F2(user2FADTO.UserName, var userDTO_Response = await _userService.Authenticate2F2(user2FADTO.UserName,
user2FADTO.Password, user2FADTO.Password,
user2FADTO.Code, user2FADTO.Code,
user2FADTO.Token2FA); user2FADTO.Token2FA);
if (userDTO_Response != null) if (userDTO_Response != null)
{ {
+1 -1
View File
@@ -8,7 +8,7 @@ namespace WorkFlowCheck.Common.DTO
{ {
public class User2FADTO public class User2FADTO
{ {
public int Id { get; set; }
public string UserName { get; set; } = null!; public string UserName { get; set; } = null!;
public string Password { get; set; } = null!; public string Password { get; set; } = null!;
public string Code { get; set; } = null!; public string Code { get; set; } = null!;
@@ -2,6 +2,8 @@
@model WorkFlowCheck.Web.Pages.Account.LoginModel @model WorkFlowCheck.Web.Pages.Account.LoginModel
@using WorkFlowCheck.Common.Helper @using WorkFlowCheck.Common.Helper
@using WorkFlowCheck.Common.DTO @using WorkFlowCheck.Common.DTO
@using Microsoft.AspNetCore.Antiforgery
@inject IAntiforgery Antiforgery
@{ @{
Layout = null; Layout = null;
ViewData["Title"] = "Bejelentkezés"; ViewData["Title"] = "Bejelentkezés";
@@ -27,20 +29,30 @@
} }
<form method="post"> <form method="post">
<meta name="csrf-token" content="@Antiforgery.GetAndStoreTokens(HttpContext).RequestToken" />
<input type="hidden" asp-for="User2FADTO.Token2FA" />
<div class="mb-3"> <div class="mb-3">
<label asp-for="UserSimpleDTO.UserName" class="form-label">Felhasználónév</label> <label asp-for="User2FADTO.UserName" class="form-label">Felhasználónév</label>
<input asp-for="UserSimpleDTO.UserName" class="form-control" /> <input asp-for="User2FADTO.UserName" class="form-control" />
<span asp-validation-for="UserSimpleDTO.UserName" class="text-danger small"></span> <span asp-validation-for="User2FADTO.UserName" class="text-danger small"></span>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label asp-for="UserSimpleDTO.Password" class="form-label">Jelszó</label> <label asp-for="User2FADTO.Password" class="form-label">Jelszó</label>
<input asp-for="UserSimpleDTO.Password" type="password" class="form-control" /> <input asp-for="User2FADTO.Password" type="password" class="form-control" />
<span asp-validation-for="UserSimpleDTO.Password" class="text-danger small"></span> <span asp-validation-for="User2FADTO.Password" class="text-danger small"></span>
</div> </div>
<div id="VerificationCode" class="mb-3">
<div class="d-grid"> <label asp-for="User2FADTO.Code" class="form-label">Megerősítő kód</label>
<button type="submit" class="btn btn-primary">Bejelentkezés</button> <input asp-for="User2FADTO.Code" class="form-control" />
<span asp-validation-for="User2FADTO.Code" class="text-danger small"></span>
</div>
<hr class="mt-4 mb-3 border-secondary">
<div id="login2F1" class="d-grid">
<button id="Login2F1Btn" type="button" class="btn btn-primary">Bejelentkezés</button>
</div>
<div id="login2F2" class="d-grid">
<button id="Login2F2Btn" type="button" class="btn btn-primary">Megerősítés</button>
</div> </div>
</form> </form>
</div> </div>
@@ -50,7 +62,91 @@
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.5/dist/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery-validation-unobtrusive@4.0.0/dist/jquery.validate.unobtrusive.min.js"></script>
<script>
$(document).ready(function () {
$('#VerificationCode').hide();
$('#login2F2').hide();
$('#Login2F2Btn').hide();
$('#Login2F1Btn').on('click', function () {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const userName = $('#User2FADTO_UserName').val();
const password = $('#User2FADTO_Password').val();
$.ajax({
url: '/Account/Login?handler=Login2F1',
type: 'POST',
headers: {
'X-CSRF-TOKEN': csrfToken,
'Content-Type': 'application/json'
},
contentType: 'application/json',
data: JSON.stringify({
UserName: userName,
Password: password
}),
success: function (result) {
if (result.success) {
$('#login2F1').hide();
$('#Login2F1Btn').hide();
$('#VerificationCode').show();
$('#login2F2').show();
$('#Login2F2Btn').show();
$('#User2FADTO_Token2FA').val(result.data)
} else {
alert('Hibás felhasználónév vagy jelszó!');
}
},
error: function () {
alert('Hiba történt a kérés során.');
}
});
});
$('#Login2F2Btn').on('click', function () {
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
const userName = $('#User2FADTO_UserName').val();
const password = $('#User2FADTO_Password').val();
const code = $('#User2FADTO_Code').val();
const token2FA = $('#User2FADTO_Token2FA').val();
$.ajax({
url: '/Account/Login?handler=Login2F2',
type: 'POST',
headers: {
'X-CSRF-TOKEN': csrfToken,
'Content-Type': 'application/json'
},
contentType: 'application/json',
data: JSON.stringify({
UserName: userName,
Password: password,
Code: code,
Token2FA: token2FA
}),
success: function (result) {
if (result.success) {
window.location.href = `/Index`;
} else {
alert('Hibás felhasználónév vagy jelszó!');
}
},
error: function (xhr) {
console.log(xhr.status);
console.log(xhr.responseText);
alert('Hiba történt a kérés során.');
}
});
});
});
</script>
<partial name="_ValidationScriptsPartial" /> <partial name="_ValidationScriptsPartial" />
</body> </body>
</html> </html>
@@ -14,7 +14,8 @@ namespace WorkFlowCheck.Web.Pages.Account
private readonly IUserService _userService; private readonly IUserService _userService;
[BindProperty] [BindProperty]
public UserDTO UserSimpleDTO { get; set; } public User2FADTO User2FADTO { get; set; }
public string ErrorMessage { get; set; } public string ErrorMessage { get; set; }
public LoginModel(IUserService userService) public LoginModel(IUserService userService)
@@ -25,14 +26,31 @@ namespace WorkFlowCheck.Web.Pages.Account
public void OnGet() public void OnGet()
{ {
} }
public async Task<IActionResult> OnPostAsync() public async Task<IActionResult> OnPostLogin2F1([FromBody] UserSimpleDTO userSimpleDTO)
{ {
var response = await _userService.Authenticate(UserSimpleDTO.UserName, UserSimpleDTO.Password); var response = await _userService.Authenticate2F1(userSimpleDTO.UserName, userSimpleDTO.Password);
if (response.IsSuccess) if (response.IsSuccess)
{ {
return new JsonResult(new { success = true, data = response.Data });
var token = response.Data.JwtToken; }
else
{
ErrorMessage = "Hibás bejelentkezés!";
return new JsonResult(new { success = false });
}
}
public async Task<IActionResult> OnPostLogin2F2([FromBody] User2FADTO user2FADTO)
{
var response = await _userService.Authenticate2F2(user2FADTO.UserName,
user2FADTO.Password,
user2FADTO.Code,
user2FADTO.Token2FA);
if (response.IsSuccess)
{
var token = response.Data.JwtToken;
Response.Cookies.Append("AuthToken", token, new CookieOptions Response.Cookies.Append("AuthToken", token, new CookieOptions
{ {
@@ -42,11 +60,11 @@ namespace WorkFlowCheck.Web.Pages.Account
Expires = DateTimeOffset.UtcNow.AddMinutes(30) Expires = DateTimeOffset.UtcNow.AddMinutes(30)
}); });
return RedirectToPage("/Index"); // vagy ahová szeretnéd return new JsonResult(new { success = true });
} }
ErrorMessage = "Hibás bejelentkezés!"; ErrorMessage = "Hibás bejelentkezés!";
return Page(); return new JsonResult(new { success = false });
} }
} }
} }
@@ -8,6 +8,8 @@ namespace WorkFlowCheck.Web.Services.Interfaces
Task<List<UserDTO>> GetAllUsers(); Task<List<UserDTO>> GetAllUsers();
Task<ApiResponseDTO<UserDTO>> UpdateUser(UserDTO userDTO); Task<ApiResponseDTO<UserDTO>> UpdateUser(UserDTO userDTO);
Task<ApiResponseDTO<UserDTO>> Authenticate(string username, string password); Task<ApiResponseDTO<UserDTO>> Authenticate(string username, string password);
Task<ApiResponseDTO<string>> Authenticate2F1(string username, string password);
Task<ApiResponseDTO<UserDTO>> Authenticate2F2(string userName, string password, string code, string token2FA);
Task<bool> DeleteUser(int id); Task<bool> DeleteUser(int id);
Task<RoleDTO> GetRole(int id); Task<RoleDTO> GetRole(int id);
+81 -4
View File
@@ -55,7 +55,7 @@ namespace WorkFlowCheck.Web.Services
} }
return retVal; return retVal;
} }
public async Task<ApiResponseDTO<UserDTO>> UpdateUser(UserDTO userDTO) public async Task<ApiResponseDTO<UserDTO>> UpdateUser(UserDTO userDTO)
{ {
try try
{ {
@@ -94,9 +94,9 @@ namespace WorkFlowCheck.Web.Services
{ {
UserName = username, UserName = username,
Password = password, Password = password,
}; };
using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, userSimpleDTO)) using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, userSimpleDTO))
{ {
@@ -120,6 +120,81 @@ namespace WorkFlowCheck.Web.Services
}; };
} }
} }
public async Task<ApiResponseDTO<string>> Authenticate2F1(string username, string password)
{
try
{
// Az API végpont meghatározása
string endpoint = $"{_httpClient.BaseAddress}api/User/Authenticate2F1";
var userSimpleDTO = new UserSimpleDTO()
{
UserName = username,
Password = password,
};
using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, userSimpleDTO))
{
httpResponseMessage.EnsureSuccessStatusCode();
var jsonString = await httpResponseMessage.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<ApiResponseDTO<string>>(jsonString);
return response ?? new ApiResponseDTO<string>
{
IsSuccess = false,
};
}
}
catch (Exception ex)
{
// Hiba visszaadása
return new ApiResponseDTO<string>
{
IsSuccess = false
};
}
}
public async Task<ApiResponseDTO<UserDTO>> Authenticate2F2(string userName, string password, string code, string token2FA)
{
try
{
string endpoint = $"{_httpClient.BaseAddress}api/User/Authenticate2F2";
var userSimpleDTO = new User2FADTO()
{
UserName = userName,
Password = password,
Code = code,
Token2FA = token2FA
};
using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, userSimpleDTO))
{
httpResponseMessage.EnsureSuccessStatusCode();
var jsonString = await httpResponseMessage.Content.ReadAsStringAsync();
var response = JsonConvert.DeserializeObject<ApiResponseDTO<UserDTO>>(jsonString);
return response ?? new ApiResponseDTO<UserDTO>
{
IsSuccess = false,
};
}
}
catch (Exception ex)
{
return new ApiResponseDTO<UserDTO>
{
IsSuccess = false
};
}
}
public async Task<bool> DeleteUser(int id) public async Task<bool> DeleteUser(int id)
{ {
string endpoint = $"{_httpClient.BaseAddress}api/User/DeleteUser/{id}"; string endpoint = $"{_httpClient.BaseAddress}api/User/DeleteUser/{id}";
@@ -326,7 +401,7 @@ namespace WorkFlowCheck.Web.Services
} }
return retVal; return retVal;
} }
public async Task<List<RoleCheckListTemplateHeaderDTO>> GetAllRoleCheckListTemplates() public async Task<List<RoleCheckListTemplateHeaderDTO>> GetAllRoleCheckListTemplates()
{ {
string endpoint = $"{_httpClient.BaseAddress}api/User/GetAllRoleCheckListTemplateHeaders"; string endpoint = $"{_httpClient.BaseAddress}api/User/GetAllRoleCheckListTemplateHeaders";
var retVal = new List<RoleCheckListTemplateHeaderDTO>(); var retVal = new List<RoleCheckListTemplateHeaderDTO>();
@@ -446,5 +521,7 @@ namespace WorkFlowCheck.Web.Services
}; };
} }
} }
} }
} }