using IdentityServer4; using IdentityServer4.Services; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Infra.EFCore; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Hosting; using System; using System.Threading.Tasks; namespace IRaCIS.Core.IdentityServer4.Account { [ApiController] [AllowAnonymous] public class AuthenticateController : Controller { private readonly IIdentityServerInteractionService _interaction; private readonly IWebHostEnvironment _environment; private readonly IRepository _userRepository; public AuthenticateController( IIdentityServerInteractionService interaction, IWebHostEnvironment environment, IRepository userRepository) { _interaction = interaction; _environment = environment; _userRepository = userRepository; } public class LoginRequest { public string UserName { get; set; } public string Password { get; set; } public string ReturnUrl { get; set; } public bool RememberLogin { get; set; } } [Route("user/login")] [HttpPost] public async Task Login([FromBody]LoginRequest request) { var a = "/connect/authorize/callback?client_id=spa&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcallback.html&response_type=code&scope=openid%20%20profile&state=05d78e28fabf4af889f408123cfd6109&code_challenge=DmFSo8DgWoL7J9rT5BLPHwIWeAKJWKGR_ZYmxCaWmEw&code_challenge_method=S256&display=popup"; var context = await _interaction.GetAuthorizationContextAsync(request.ReturnUrl); var user = await _userRepository .FirstOrDefaultAsync(usr => usr.Password == request.Password && usr.UserName == request.UserName); if (user != null && context != null) { AuthenticationProperties props = null; if (request.RememberLogin) { props = new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromDays(1)) }; }; var identityServerUser = new IdentityServerUser(user.Id.ToString()) { DisplayName = request.UserName }; await HttpContext.SignInAsync(identityServerUser, props); return new JsonResult(new { RedirectUrl = request.ReturnUrl, IsOk = true }); } return Unauthorized(); } [HttpGet] [Route("user/logout")] public async Task Logout(string logoutId) { var context = await _interaction.GetLogoutContextAsync(logoutId); bool showSignoutPrompt = true; if (context?.ShowSignoutPrompt == false) { // it's safe to automatically sign-out showSignoutPrompt = false; } if (User?.Identity.IsAuthenticated == true) { // delete local authentication cookie await HttpContext.SignOutAsync(); } // no external signout supported for now (see \Quickstart\Account\AccountController.cs TriggerExternalSignout) return Ok(new { showSignoutPrompt, ClientName = string.IsNullOrEmpty(context?.ClientName) ? context?.ClientId : context?.ClientName, context?.PostLogoutRedirectUri, context?.SignOutIFrameUrl, logoutId }); } [HttpGet] [Route("Error")] public async Task Error(string errorId) { // retrieve error details from identityserver var message = await _interaction.GetErrorContextAsync(errorId); if (message != null) { if (!_environment.IsDevelopment()) { // only show in development message.ErrorDescription = null; } } return Ok(message); } } }