using Duende.IdentityServer; using Duende.IdentityServer.Models; using Duende.IdentityServer.Services; using Easy.Api; using Identity.Infrastructure.Dtos; using Identity.Infrastructure.Models; using Identity.Infrastructure.Repositories; using Microsoft.AspNetCore.Authentication; namespace Identity.Realization; public class Spa : ApiService { private readonly IIdentityServerInteractionService _interaction; private readonly IServerUrls _serverUrls; private readonly IUserRepository _userRepository; private readonly IHttpContextAccessor Accessor; public Spa(IIdentityServerInteractionService interaction, IServerUrls serverUrls, IUserRepository userRepository, IHttpContextAccessor httpContextAccessor) { _interaction = interaction; _serverUrls = serverUrls; _userRepository = userRepository; Accessor = httpContextAccessor; } public async Task> Login(LoginDto model) { var user = await _userRepository.PasswordSignInAsync(model.Username, model.Password); if (user == null) return ApiResult.Value("").CustomStatusMessage("UserLoginPassword", "用户名或密码无效"); var isUser = new IdentityServerUser(user.Id.ToString()) { DisplayName = user.NickName, }; var props = new AuthenticationProperties { IsPersistent = model.Remember }; await Accessor.HttpContext.SignInAsync(isUser.CreatePrincipal(), props); var url = model.ReturnUrl != null ? Uri.UnescapeDataString(model.ReturnUrl) : null; var authzContext = await _interaction.GetAuthorizationContextAsync(url); return ApiResult.Value(authzContext != null ? url : _serverUrls.BaseUrl).SUCCESS(); } public async Task> Consent(ConsentDto model) { var url = Uri.UnescapeDataString(model.ReturnUrl); var authzContext = await _interaction.GetAuthorizationContextAsync(url); When.Is(authzContext == null, "错误"); if (model.Deny) { await _interaction.DenyAuthorizationAsync(authzContext, AuthorizationError.AccessDenied); } else { await _interaction.GrantConsentAsync(authzContext, new ConsentResponse { RememberConsent = model.Remember, ScopesValuesConsented = authzContext.ValidatedResources.RawScopeValues }); } return ApiResult.Value(url).SUCCESS(); } public async Task> GetContext(string returnUrl) { var authzContext = await _interaction.GetAuthorizationContextAsync(returnUrl); When.Is(authzContext == null, "没有上下文"); return ApiResult.Value(new ContextModel { LoginHint = authzContext.LoginHint, IdP = authzContext.IdP, Tenant = authzContext.Tenant, Scopes = authzContext.ValidatedResources.RawScopeValues, Client = authzContext.Client.ClientName ?? authzContext.Client.ClientId }).SUCCESS(); } public async Task> GetError(string errorId) { var errorInfo = await _interaction.GetErrorContextAsync(errorId); return ApiResult.Value(new ErrorModel() { Error = errorInfo.Error, ErrorDescription = errorInfo.ErrorDescription }).SUCCESS(); } public async Task> Logout(string logoutId) { var logoutInfo = await _interaction.GetLogoutContextAsync(logoutId); await Accessor.HttpContext.SignOutAsync(); return ApiResult.Value(new LogOutModel() { PostLogoutRedirectUri = logoutInfo.PostLogoutRedirectUri, SignOutIFrameUrl = logoutInfo.SignOutIFrameUrl }).SUCCESS(); } public async Task> GetLogout(string logoutId) { var logoutInfo = await _interaction.GetLogoutContextAsync(logoutId); if (logoutInfo != null) { if (!logoutInfo.ShowSignoutPrompt || !Accessor.HttpContext.User.Identity.IsAuthenticated) { await Accessor.HttpContext.SignOutAsync(); return ApiResult.Value(new LogOutModel() { PostLogoutRedirectUri = logoutInfo.PostLogoutRedirectUri, SignOutIFrameUrl = logoutInfo.SignOutIFrameUrl }).SUCCESS(); } } return ApiResult.Value(new LogOutModel() { Prompt = Accessor.HttpContext.User.Identity.IsAuthenticated }).RETRY("未授权"); } }