refactor(auth): Refactoring der Login-Methoden für OpenAPI-Kompatibilität
– Die Login-Methoden wurden überarbeitet, um NotImplementedException auszulösen und OpenAPI (Swagger) und Skalar zu konfigurieren. – Unnötige using-Anweisungen wurden entfernt, um den Code zu optimieren.
This commit is contained in:
parent
2d3987b81e
commit
a85397a363
@ -5,197 +5,148 @@ using Microsoft.AspNetCore.Authentication.Cookies;
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using DigitalData.UserManager.Application.DTOs.Auth;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using EnvelopeGenerator.GeneratorAPI.Models;
|
using EnvelopeGenerator.GeneratorAPI.Models;
|
||||||
|
|
||||||
namespace EnvelopeGenerator.GeneratorAPI.Controllers
|
namespace EnvelopeGenerator.GeneratorAPI.Controllers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus.
|
||||||
|
/// </summary>
|
||||||
|
[Route("api/[controller]")]
|
||||||
|
[ApiController]
|
||||||
|
public partial class AuthController : ControllerBase
|
||||||
{
|
{
|
||||||
|
private readonly ILogger<AuthController> _logger;
|
||||||
|
private readonly IUserService _userService;
|
||||||
|
private readonly IDirectorySearchService _dirSearchService;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus.
|
/// Initializes a new instance of the <see cref="AuthController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("api/[controller]")]
|
/// <param name="logger">The logger instance.</param>
|
||||||
[ApiController]
|
/// <param name="userService">The user service instance.</param>
|
||||||
public partial class AuthController : ControllerBase
|
/// <param name="dirSearchService">The directory search service instance.</param>
|
||||||
|
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
|
||||||
{
|
{
|
||||||
private readonly ILogger<AuthController> _logger;
|
_logger = logger;
|
||||||
private readonly IUserService _userService;
|
_userService = userService;
|
||||||
private readonly IDirectorySearchService _dirSearchService;
|
_dirSearchService = dirSearchService;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="AuthController"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="logger">The logger instance.</param>
|
|
||||||
/// <param name="userService">The user service instance.</param>
|
|
||||||
/// <param name="dirSearchService">The directory search service instance.</param>
|
|
||||||
public AuthController(ILogger<AuthController> logger, IUserService userService, IDirectorySearchService dirSearchService)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_userService = userService;
|
|
||||||
_dirSearchService = dirSearchService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
|
||||||
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Gibt eine HTTP 200 oder 401.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// Sample request:
|
|
||||||
///
|
|
||||||
/// POST /api/auth?cookie=true
|
|
||||||
/// {
|
|
||||||
/// "username": "MaxMustermann",
|
|
||||||
/// "password": "Geheim123!"
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// POST /api/auth?cookie=true
|
|
||||||
/// {
|
|
||||||
/// "id": "1",
|
|
||||||
/// "password": "Geheim123!"
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// </remarks>
|
|
||||||
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
|
||||||
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
|
||||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
|
||||||
[AllowAnonymous]
|
|
||||||
[HttpPost]
|
|
||||||
public async Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
bool isValid = _dirSearchService.ValidateCredentials(login.Username, login.Password);
|
|
||||||
|
|
||||||
if (!isValid)
|
|
||||||
return Unauthorized();
|
|
||||||
|
|
||||||
//find the user
|
|
||||||
var uRes = await _userService.ReadByUsernameAsync(login.Username);
|
|
||||||
if (!uRes.IsSuccess || uRes.Data is null)
|
|
||||||
{
|
|
||||||
return Forbid();
|
|
||||||
}
|
|
||||||
|
|
||||||
UserReadDto user = uRes.Data;
|
|
||||||
|
|
||||||
// Create claims
|
|
||||||
var claims = new List<Claim>
|
|
||||||
{
|
|
||||||
new (ClaimTypes.NameIdentifier, user.Id.ToString()),
|
|
||||||
new (ClaimTypes.Name, user.Username),
|
|
||||||
new (ClaimTypes.Surname, user.Name!),
|
|
||||||
new (ClaimTypes.GivenName, user.Prename!),
|
|
||||||
new (ClaimTypes.Email, user.Email!),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create claimsIdentity
|
|
||||||
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
||||||
|
|
||||||
// Create authProperties
|
|
||||||
var authProperties = new AuthenticationProperties
|
|
||||||
{
|
|
||||||
IsPersistent = true,
|
|
||||||
AllowRefresh = true,
|
|
||||||
ExpiresUtc = DateTime.Now.AddMinutes(180)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sign in
|
|
||||||
await HttpContext.SignInAsync(
|
|
||||||
CookieAuthenticationDefaults.AuthenticationScheme,
|
|
||||||
new ClaimsPrincipal(claimsIdentity),
|
|
||||||
authProperties);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
|
||||||
/// <returns>
|
|
||||||
/// Gibt eine HTTP 200 oder 401.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// Sample request:
|
|
||||||
///
|
|
||||||
/// POST /api/auth/form
|
|
||||||
/// {
|
|
||||||
/// "username": "MaxMustermann",
|
|
||||||
/// "password": "Geheim123!"
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// </remarks>
|
|
||||||
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
|
||||||
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
|
||||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
|
||||||
[AllowAnonymous]
|
|
||||||
[HttpPost]
|
|
||||||
[Route("form")]
|
|
||||||
public async Task<IActionResult> Login([FromForm] Login login)
|
|
||||||
{
|
|
||||||
return await Login(login, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>
|
|
||||||
/// Gibt eine HTTP 200 oder 401.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// Sample request:
|
|
||||||
///
|
|
||||||
/// POST /api/auth/logout
|
|
||||||
///
|
|
||||||
/// </remarks>
|
|
||||||
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
|
|
||||||
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
|
||||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
|
||||||
[Authorize]
|
|
||||||
[HttpPost("logout")]
|
|
||||||
public async Task<IActionResult> Logout()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Prüft, ob der Benutzer ein autorisiertes Token hat.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// Sample request:
|
|
||||||
///
|
|
||||||
/// GET /api/auth
|
|
||||||
///
|
|
||||||
/// </remarks>
|
|
||||||
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
|
|
||||||
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
|
|
||||||
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
|
||||||
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
|
||||||
[Authorize]
|
|
||||||
[HttpGet]
|
|
||||||
public IActionResult IsAuthenticated() => Ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Wenn 'cookie' wahr ist, wird das Token als HTTP-Only-Cookie zurückgegeben.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||||
|
/// <param name="cookie">Wenn wahr, wird das JWT-Token auch als HTTP-Only-Cookie gesendet.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth?cookie=true
|
||||||
|
/// {
|
||||||
|
/// "username": "MaxMustermann",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// POST /api/auth?cookie=true
|
||||||
|
/// {
|
||||||
|
/// "id": "1",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||||
|
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost]
|
||||||
|
public Task<IActionResult> Login([FromBody] Login login, [FromQuery] bool cookie = false)
|
||||||
|
{
|
||||||
|
// added to configure open API (swagger and scalar)
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Authentifiziert einen Benutzer und generiert ein JWT-Token. Das Token wird als HTTP-only-Cookie zurückgegeben.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="login">Benutzeranmeldedaten (Benutzername und Passwort).</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth/form
|
||||||
|
/// {
|
||||||
|
/// "username": "MaxMustermann",
|
||||||
|
/// "password": "Geheim123!"
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreiche Anmeldung. Gibt das JWT-Token im Antwortkörper oder als Cookie zurück, wenn 'cookie' wahr ist.</response>
|
||||||
|
/// <response code="401">Unbefugt. Ungültiger Benutzername oder Passwort.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost]
|
||||||
|
[Route("form")]
|
||||||
|
public Task<IActionResult> Login([FromForm] Login login)
|
||||||
|
{
|
||||||
|
// added to configure open API (swagger and scalar)
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// Gibt eine HTTP 200 oder 401.
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// POST /api/auth/logout
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat.</response>
|
||||||
|
/// <response code="401">Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[Authorize]
|
||||||
|
[HttpPost("logout")]
|
||||||
|
public async Task<IActionResult> Logout()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Unexpected error occurred.\n{ErrorMessage}", ex.Message);
|
||||||
|
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prüft, ob der Benutzer ein autorisiertes Token hat.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample request:
|
||||||
|
///
|
||||||
|
/// GET /api/auth
|
||||||
|
///
|
||||||
|
/// </remarks>
|
||||||
|
/// <response code="200">Wenn es einen autorisierten Cookie gibt.</response>
|
||||||
|
/// <response code="401">Wenn kein Cookie vorhanden ist oder nicht autorisierte.</response>
|
||||||
|
[ProducesResponseType(typeof(string), StatusCodes.Status200OK, "text/javascript")]
|
||||||
|
[ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)]
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult IsAuthenticated() => Ok();
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user