80 lines
3.1 KiB
C#
80 lines
3.1 KiB
C#
using Microsoft.AspNetCore.Identity;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using PlaylistShared.Api.Entities;
|
||
using PlaylistShared.Api.Services;
|
||
using System.Security.Claims;
|
||
|
||
namespace PlaylistShared.Api.Controllers;
|
||
|
||
[ApiController]
|
||
[Route("api/[controller]")]
|
||
public class OpenIdController : ControllerBase
|
||
{
|
||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||
private readonly UserManager<ApplicationUser> _userManager;
|
||
private readonly JwtService _jwtService;
|
||
private readonly IConfiguration _configuration;
|
||
private readonly UserSessionService _userSessionService;
|
||
|
||
public OpenIdController(
|
||
SignInManager<ApplicationUser> signInManager,
|
||
UserManager<ApplicationUser> userManager,
|
||
JwtService jwtService,
|
||
IConfiguration configuration,
|
||
UserSessionService userSessionService)
|
||
{
|
||
_signInManager = signInManager;
|
||
_userManager = userManager;
|
||
_jwtService = jwtService;
|
||
_configuration = configuration;
|
||
_userSessionService = userSessionService;
|
||
}
|
||
|
||
[HttpGet("login")]
|
||
public IActionResult Login(string? returnUrl = null)
|
||
{
|
||
var redirectUrl = Url.Action(nameof(Callback), "OpenId", new { returnUrl });
|
||
var properties = _signInManager.ConfigureExternalAuthenticationProperties("Keycloak", redirectUrl);
|
||
return Challenge(properties, "Keycloak");
|
||
}
|
||
|
||
[HttpGet("callback")]
|
||
public async Task<IActionResult> Callback(string? returnUrl = null, string? remoteError = null)
|
||
{
|
||
if (remoteError != null)
|
||
return BadRequest($"Ошибка внешнего входа: {remoteError}");
|
||
|
||
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||
if (info == null)
|
||
return BadRequest("Не удалось получить информацию от провайдера");
|
||
|
||
var email = info.Principal.FindFirst(ClaimTypes.Email)?.Value;
|
||
var userName = info.Principal.FindFirst(ClaimTypes.Name)?.Value ?? email;
|
||
|
||
var user = await _userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey);
|
||
if (user == null)
|
||
{
|
||
user = await _userManager.FindByEmailAsync(email);
|
||
if (user == null)
|
||
{
|
||
user = new ApplicationUser
|
||
{
|
||
UserName = userName,
|
||
Email = email
|
||
};
|
||
var createResult = await _userManager.CreateAsync(user);
|
||
if (!createResult.Succeeded)
|
||
return BadRequest(createResult.Errors);
|
||
}
|
||
|
||
var loginResult = await _userManager.AddLoginAsync(user, info);
|
||
if (!loginResult.Succeeded)
|
||
return BadRequest(loginResult.Errors);
|
||
}
|
||
|
||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||
await _userSessionService.GetOrCreateCurrentSessionAsync(user.Id);
|
||
var (token, refreshToken, _) = await _jwtService.GenerateTokenAsync(user);
|
||
return Redirect($"{_configuration["Client:BaseUrl"]}/auth-callback?token={token}&refreshToken={refreshToken}");
|
||
}
|
||
} |