| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- using Abp.Runtime.Security;
- using Abp.UI;
- using Microsoft.AspNetCore.Identity;
- using Microsoft.AspNetCore.Mvc;
- using VberAdmin.Authentication.External;
- using VberAdmin.Authorization;
- using VberAdmin.Authorization.Users;
- using VberAdmin.Models.TokenAuth;
- using VberZero.AppService.Authorization;
- using VberZero.Authorization;
- using VberZero.Authorization.Users;
- using VberZero.BaseSystem.Users;
- using VberZero.Jwt;
- using VberZero.MultiTenancy;
- namespace VberAdmin.Controllers;
- [Route("api/[controller]/[action]")]
- public class TokenAuthController : VberAdminControllerBase
- {
- private readonly LogInManager _logInManager;
- private readonly ITenantCache _tenantCache;
- private readonly VzLoginResultTypeHelper _vzLoginResultTypeHelper;
- private readonly TokenAuthConfiguration _configuration;
- private readonly IExternalAuthConfiguration _externalAuthConfiguration;
- private readonly IExternalAuthManager _externalAuthManager;
- private readonly UserRegistrationManager _userRegistrationManager;
- private readonly UserManager _userManager;
- public TokenAuthController(
- LogInManager logInManager,
- ITenantCache tenantCache,
- VzLoginResultTypeHelper vzLoginResultTypeHelper,
- TokenAuthConfiguration configuration,
- IExternalAuthConfiguration externalAuthConfiguration,
- IExternalAuthManager externalAuthManager,
- UserRegistrationManager userRegistrationManager, UserManager userManager)
- {
- _logInManager = logInManager;
- _tenantCache = tenantCache;
- _vzLoginResultTypeHelper = vzLoginResultTypeHelper;
- _configuration = configuration;
- _externalAuthConfiguration = externalAuthConfiguration;
- _externalAuthManager = externalAuthManager;
- _userRegistrationManager = userRegistrationManager;
- _userManager = userManager;
- }
- [HttpPost]
- public async Task<AuthenticateResultModel> Authenticate([FromBody] AuthenticateModel model)
- {
- var tenancyName = await _userManager.GetTenancyNameAsync(model.UsernameOrEmailOrPhone);
- var loginResult = await GetLoginResultAsync(
- model.UsernameOrEmailOrPhone,
- model.Password,
- tenancyName
- );
- var accessToken = JwtHelper.CreateAccessToken(loginResult.Identity, _configuration);
- return new AuthenticateResultModel
- {
- AccessToken = accessToken,
- EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
- ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds,
- UserId = loginResult.User.Id
- };
- }
- [HttpGet]
- public List<ExternalLoginProviderInfoModel> GetExternalAuthenticationProviders()
- {
- return ObjectMapper.Map<List<ExternalLoginProviderInfoModel>>(_externalAuthConfiguration.Providers);
- }
- [HttpPost]
- public async Task<ExternalAuthenticateResultModel> ExternalAuthenticate([FromBody] ExternalAuthenticateModel model)
- {
- var externalUser = await GetExternalUserInfo(model);
- var loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());
- switch (loginResult.Result)
- {
- case VzLoginResultType.Success:
- {
- var accessToken = JwtHelper.CreateAccessToken(loginResult.Identity, _configuration);
- return new ExternalAuthenticateResultModel
- {
- AccessToken = accessToken,
- EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
- ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
- };
- }
- case VzLoginResultType.UnknownExternalLogin:
- {
- var newUser = await RegisterExternalUserAsync(externalUser);
- if (!newUser.IsActive)
- {
- return new ExternalAuthenticateResultModel
- {
- WaitingForActivation = true
- };
- }
- // Try to login again with newly registered user!
- loginResult = await _logInManager.LoginAsync(new UserLoginInfo(model.AuthProvider, model.ProviderKey, model.AuthProvider), GetTenancyNameOrNull());
- if (loginResult.Result != VzLoginResultType.Success)
- {
- throw _vzLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
- loginResult.Result,
- model.ProviderKey,
- GetTenancyNameOrNull()
- );
- }
- var accessToken = JwtHelper.CreateAccessToken(loginResult.Identity, _configuration);
- return new ExternalAuthenticateResultModel
- {
- AccessToken = accessToken,
- EncryptedAccessToken = GetEncryptedAccessToken(accessToken),
- ExpireInSeconds = (int)_configuration.Expiration.TotalSeconds
- };
- }
- default:
- {
- throw _vzLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(
- loginResult.Result,
- model.ProviderKey,
- GetTenancyNameOrNull()
- );
- }
- }
- }
- private async Task<User> RegisterExternalUserAsync(ExternalAuthUserInfo externalUser)
- {
- var user = await _userRegistrationManager.RegisterAsync(
- externalUser.Name,
- externalUser.Surname,
- externalUser.EmailAddress,
- externalUser.EmailAddress,
- VberZero.BaseSystem.Users.User.CreateRandomPassword(),
- true
- );
- user.Logins = new List<UserLogin>
- {
- new UserLogin
- {
- LoginProvider = externalUser.Provider,
- ProviderKey = externalUser.ProviderKey,
- TenantId = user.TenantId
- }
- };
- await CurrentUnitOfWork.SaveChangesAsync();
- return user;
- }
- private async Task<ExternalAuthUserInfo> GetExternalUserInfo(ExternalAuthenticateModel model)
- {
- var userInfo = await _externalAuthManager.GetUserInfo(model.AuthProvider, model.ProviderAccessCode);
- if (userInfo.ProviderKey != model.ProviderKey)
- {
- throw new UserFriendlyException(L("CouldNotValidateExternalUser"));
- }
- return userInfo;
- }
- private string GetTenancyNameOrNull()
- {
- if (!AbpSession.TenantId.HasValue)
- {
- return null;
- }
- return _tenantCache.GetOrNull(AbpSession.TenantId.Value)?.TenancyName;
- }
- private async Task<AbpLoginResult> GetLoginResultAsync(string usernameOrEmailAddress, string password, string tenancyName)
- {
- var loginResult = await _logInManager.LoginAsync(usernameOrEmailAddress, password, tenancyName);
- switch (loginResult.Result)
- {
- case VzLoginResultType.Success:
- return loginResult;
- default:
- throw _vzLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, usernameOrEmailAddress, tenancyName);
- }
- }
- private string GetEncryptedAccessToken(string accessToken)
- {
- return SimpleStringCipher.Instance.Encrypt(accessToken);
- }
- }
|