초기커밋
This commit is contained in:
212
BrokerApiCore/Services/UserAuthService.cs
Normal file
212
BrokerApiCore/Services/UserAuthService.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text;
|
||||
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
using ServerCore; using ServerBase;
|
||||
|
||||
using ServerCommon;
|
||||
|
||||
namespace BrokerCore.Services;
|
||||
|
||||
using BrokerBusinessLog;
|
||||
|
||||
using Repository;
|
||||
|
||||
using Common;
|
||||
|
||||
using Entity;
|
||||
|
||||
public class UserAuthService
|
||||
{
|
||||
private readonly PlanetUserEntity m_planet_user_entity;
|
||||
private readonly SsoAccountRepo m_sso_account_repo;
|
||||
private readonly IServerLogic m_server_logic;
|
||||
|
||||
public string AccountId
|
||||
=> m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().AccountId;
|
||||
|
||||
// public string Email { get; set; } = string.Empty;
|
||||
public string UserGuid
|
||||
=> m_planet_user_entity.getEntityAttributeNotNull<AccountAttribute>().UserGuid;
|
||||
|
||||
public string Nickname
|
||||
=> m_planet_user_entity.getEntityAttributeNotNull<NicknameAttribute>().Nickname;
|
||||
|
||||
public IServerLogic ServerLogic => m_server_logic;
|
||||
|
||||
public PlanetUserEntity PlanetUserEntity => m_planet_user_entity;
|
||||
|
||||
private ServerConfigMetaverseBroker? getServerConfig()
|
||||
{
|
||||
return m_server_logic.getServerConfig() as ServerConfigMetaverseBroker;
|
||||
}
|
||||
|
||||
public UserAuthService(SsoAccountRepo ssoAccountRepo, IServerLogic serverLogic)
|
||||
{
|
||||
m_sso_account_repo = ssoAccountRepo;
|
||||
m_server_logic = serverLogic;
|
||||
m_planet_user_entity = new PlanetUserEntity(serverLogic);
|
||||
m_planet_user_entity.onInit().Wait();
|
||||
}
|
||||
|
||||
public async Task<Result> authByWebPortalToken(string webPortalToken, string? planetId = null)
|
||||
{
|
||||
if (planetId is not null)
|
||||
{
|
||||
m_planet_user_entity.setPlanetId(planetId);
|
||||
}
|
||||
|
||||
var m_sso_jwt_secret_key = getServerConfig()?.SsoAccountAuthJwtSecretKey ?? string.Empty;
|
||||
Guard.Against.isNullOrEmptyOrWhiteSpace(m_sso_jwt_secret_key, ServerErrorCode.InternalServerError,
|
||||
()=>"SSO JWT secret key is required in server config");
|
||||
|
||||
var jwt_result = verifySsoAccountAuthJwt(webPortalToken,
|
||||
m_sso_jwt_secret_key,
|
||||
out var account_id, out var account_type, out var access_token);
|
||||
if (jwt_result.isFail())
|
||||
{
|
||||
var error_msg = $"Broker Api Failed to Auth From Jwt !!! : {jwt_result.toBasicString()}, {webPortalToken}";
|
||||
Log.getLogger().error(error_msg);
|
||||
return jwt_result;
|
||||
}
|
||||
|
||||
var result = await authByAccount(account_id);
|
||||
if (result.isSuccess())
|
||||
{
|
||||
if (planetId is not null)
|
||||
{
|
||||
// BrokerBusinessLogger.collectLog(m_planet_user_entity, LogActionType.BrokerApiUserLogin, new UserAuthLogInfo
|
||||
// {
|
||||
// AccountId = account_id,
|
||||
// UserGuid = UserGuid,
|
||||
// Nickname = Nickname,
|
||||
// });
|
||||
|
||||
BusinessLogger.collectLog(m_planet_user_entity,
|
||||
new PlanetUserAuthBusinessLog(
|
||||
new PlanetUserAuthLogData { AccountId = account_id, UserGuid = UserGuid, Nickname = Nickname, },
|
||||
LogActionType.BrokerApiUserLogin));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<Result> authFromEmail(string email)
|
||||
{
|
||||
var (result, sso_account) = await m_sso_account_repo.findOneByEmail(email);
|
||||
Guard.Against.resultFail(result);
|
||||
Guard.Against.isNull(sso_account, ServerErrorCode.AccountNotFound, ()=>"sso account not found");
|
||||
|
||||
result = await authByAccount(sso_account.Id.ToString());
|
||||
Guard.Against.resultFail(result);
|
||||
Guard.Against.isNull(sso_account, ServerErrorCode.UserNotFound, ()=>"user not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
// todo: JwtParser를 사용해서 수정할 것
|
||||
private Result verifySsoAccountAuthJwt(string ssoJwt
|
||||
, string ssoJwtSecret
|
||||
, out string id, out AccountType accountType, out UInt64 accessToken)
|
||||
{
|
||||
id = string.Empty;
|
||||
accountType = AccountType.None;
|
||||
accessToken = 0;
|
||||
|
||||
var result = new Result();
|
||||
var err_msg = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
var token_handler = new JwtSecurityTokenHandler();
|
||||
var validation_parameters = getValidationUserTokenParameters(ssoJwtSecret);
|
||||
|
||||
var claim = token_handler.ValidateToken(ssoJwt, validation_parameters, out var validated_token);
|
||||
// account id
|
||||
id = claim.Claims.FirstOrDefault(x => x.Type == "id")?.Value ?? string.Empty;
|
||||
// account type
|
||||
accountType = claim.Claims.FirstOrDefault(x => x.Type == "accountType")?.Value
|
||||
?.convertEnumTypeAndValueStringToEnum(AccountType.None) ?? AccountType.None;
|
||||
// access token
|
||||
var access_token_string = claim.Claims.FirstOrDefault(x => x.Type == "accessToken")?.Value;
|
||||
accessToken = Convert.ToUInt64(access_token_string);
|
||||
}
|
||||
catch (SecurityTokenExpiredException e)
|
||||
{
|
||||
err_msg = $"Expired WebAuthJWT !!! : SecurityTokenExpiredException:{e}";
|
||||
result.setFail(ServerErrorCode.ExpiredUserJwt, err_msg);
|
||||
}
|
||||
catch (SecurityTokenException e)
|
||||
{
|
||||
err_msg = $"Failed to verify WebAuthJWT !!! : SecurityTokenException:{e}";
|
||||
result.setFail(ServerErrorCode.InvalidUserJwt, err_msg);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
err_msg = $"Exception !!!, WebAuthJWT !!! : Exception:{e}";
|
||||
result.setFail(ServerErrorCode.InvalidUserJwt, err_msg);
|
||||
}
|
||||
|
||||
if (result.isFail())
|
||||
{
|
||||
result = verifyForTestUserToken(ssoJwt, ssoJwtSecret, out id, out accountType, out accessToken);
|
||||
}
|
||||
|
||||
Guard.Against.resultFail(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// 치트를 허용하도록 처리함
|
||||
private Result verifyForTestUserToken(string ssoJwt
|
||||
, string ssoJwtSecret
|
||||
, out string id, out AccountType accountType, out UInt64 accessToken)
|
||||
{
|
||||
var splits = ssoJwt.Split('|');
|
||||
if (splits.Length < 1 || splits[1] != ssoJwtSecret)
|
||||
{
|
||||
id = string.Empty;
|
||||
accountType = AccountType.None;
|
||||
accessToken = 0;
|
||||
return new Result
|
||||
{
|
||||
ErrorCode = ServerErrorCode.InvalidUserJwt, ResultString = "Failed to verify WebAuthJWT"
|
||||
};
|
||||
}
|
||||
|
||||
id = splits[0];
|
||||
accountType = AccountType.None;
|
||||
try
|
||||
{
|
||||
accessToken = Convert.ToUInt64(id);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
accessToken = 0;
|
||||
}
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
private static TokenValidationParameters getValidationUserTokenParameters(string sdsoAccountAuthJwtSecretKey)
|
||||
{
|
||||
return new TokenValidationParameters()
|
||||
{
|
||||
ValidateLifetime = true,
|
||||
ValidateAudience = false,
|
||||
ValidateIssuer = false,
|
||||
ValidIssuer = "",
|
||||
ValidAudience = "",
|
||||
IssuerSigningKey =
|
||||
new SymmetricSecurityKey(
|
||||
Encoding.UTF8.GetBytes(
|
||||
sdsoAccountAuthJwtSecretKey))
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Result> authByAccount(string accountId)
|
||||
{
|
||||
var action = m_planet_user_entity.getEntityActionNotNull<UserAuthAction>();
|
||||
return await action.findAndSetAllAttributeByAccountId(accountId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user