using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Yi.Framework.Ddd.Application;
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
using Yi.Framework.Rbac.Domain.Authorization;
using Yi.Framework.Rbac.Domain.Managers;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Rbac.Application.Services.Authentication
{
///
/// 第三方授权服务
///
public class AuthService : YiCrudAppService
{
private HttpContext HttpContext { get; set; }
private ILogger _logger;
private ISqlSugarRepository _repository;
private IAccountManager _accountManager;
public AuthService(IAccountManager accountManager, IHttpContextAccessor httpContextAccessor, ILogger logger, ISqlSugarRepository repository) : base(repository)
{
_logger = logger;
HttpContext = httpContextAccessor.HttpContext ?? throw new ApplicationException("未注册Http");
_repository = repository;
_accountManager = accountManager;
}
///
/// 第三方oauth登录
///
///
/// code是为了swagger更好的处理和显示
///
///
[HttpGet("auth/oauth/login/{scheme}")]
public async Task AuthOauthLoginAsync([FromRoute] string scheme, [FromQuery] string code)
{
(var openId, var _) = await GetOpenIdAndNameAsync(scheme);
var authEntity = await _repository.GetAsync(x => x.OpenId == openId && x.AuthType == scheme);
if (authEntity is null)
{
throw new UserFriendlyException("第三方登录失败,请先注册后,在个人中心进行绑定该第三方后使用");
}
var accessToken = await _accountManager.GetTokenByUserIdAsync(authEntity.UserId);
return accessToken;
}
///
/// 第三方oauth绑定
///
///
/// code是为了swagger更好的处理和显示
///
///
[HttpPost("auth/oauth/bind/{scheme}")]
[Authorize]
public async Task AuthOauthBindAsync([FromRoute] string scheme, [FromQuery] string code)
{
(var openId, var name) = await GetOpenIdAndNameAsync(scheme);
var userId = CurrentUser.Id;
var authEntityAny = await _repository.IsAnyAsync(x => x.OpenId == openId && x.AuthType == scheme);
if (authEntityAny)
{
throw new UserFriendlyException("绑定失败,该第三方账号已被注册");
}
var authAggregateRoot = new AuthAggregateRoot(scheme, userId ?? Guid.Empty, openId, name);
await _repository.InsertAsync(authAggregateRoot);
}
private async Task<(string, string)> GetOpenIdAndNameAsync(string scheme)
{
var authenticateResult = await HttpContext.AuthenticateAsync(scheme);
if (!authenticateResult.Succeeded)
{
throw new UserFriendlyException(authenticateResult.Failure.Message);
}
var openidClaim = authenticateResult.Principal.Claims.Where(x => x.Type == "urn:openid").FirstOrDefault();
var nameClaim = authenticateResult.Principal.Claims.Where(x => x.Type == "urn:name").FirstOrDefault();
return (openidClaim.Value, nameClaim.Value);
}
///
/// 获取当前账户的授权信息
///
///
///
[Authorize]
public async Task> GetListAccountAsync(AuthGetListInput input)
{
input.UserId = CurrentUser.Id;
input.MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount;
input.SkipCount = 1;
return (await GetListAsync(input)).Items;
}
public override async Task> GetListAsync(AuthGetListInput input)
{
RefAsync total = 0;
var entities = await _repository._DbQueryable.WhereIF(input.UserId is not null, x => x.UserId == input.UserId)
.WhereIF(!string.IsNullOrEmpty(input.AuthType), x => x.AuthType == input.AuthType)
.WhereIF(!string.IsNullOrEmpty(input.OpenId), x => x.OpenId == input.OpenId)
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities));
}
[RemoteService(IsEnabled = false)]
public override Task UpdateAsync(Guid id, AuthOutputDto input)
{
throw new NotImplementedException();
}
///
/// 删除第三方授权
///
///
///
[RemoteService(IsEnabled = true)]
public override Task DeleteAsync(IEnumerable id)
{
return base.DeleteAsync(id);
}
[RemoteService(IsEnabled = false)]
public override Task CreateAsync(AuthOutputDto input)
{
throw new NotImplementedException();
}
}
}