Na most van kész a 2 faktoros authentikáció ! :)
This commit is contained in:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user