using Furion;
using Furion.FriendlyException;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Myshipping.Core.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace Myshipping.Core
{
///
/// API接口调用用户鉴权Filter
///
public class ApiUserFilter : IAsyncActionFilter
{
public Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
var attrAllowAnonymous = actionDescriptor.EndpointMetadata.FirstOrDefault(x => x.GetType() == typeof(AllowAnonymousAttribute));
var attrApiUser = actionDescriptor.EndpointMetadata.FirstOrDefault(x => x.GetType() == typeof(ApiUserAttribute));
if (attrAllowAnonymous != null && attrApiUser != null)
{
var apiUser = attrApiUser as ApiUserAttribute;
if (context.HttpContext.Request.Headers.ContainsKey(CommonConst.API_USER_HEADER_KEY)
&& context.HttpContext.Request.Headers.ContainsKey(CommonConst.API_USER_HEADER_SECRET))
{
var key = context.HttpContext.Request.Headers[CommonConst.API_USER_HEADER_KEY].ToString();
var secret = context.HttpContext.Request.Headers[CommonConst.API_USER_HEADER_SECRET].ToString();
var httpContext = App.GetService().HttpContext;
var repApiAuth = App.GetService>();
var repTenant = App.GetService>();
var repUser = App.GetService>();
//未设置ApiCode时,使用方法名称
if (string.IsNullOrEmpty(apiUser.ApiCode))
{
apiUser.ApiCode = actionDescriptor.MethodInfo.Name;
}
var auth = repApiAuth.AsQueryable().Filter(null, true).First(x =>
x.ApiCode == apiUser.ApiCode
&& x.ApiKey == key
&& x.ApiSecret == secret
&& x.IsDeleted == false
&& x.IsDisable == false);
if (auth != null && (!auth.ExpireDate.HasValue || auth.ExpireDate > DateTime.Now))
{
var tenant = repTenant.AsQueryable().Filter(null, true).First(x => x.Id == auth.TenantId);
var user = repUser.AsQueryable().Filter(null, true).First(x => x.Id == auth.UserId);
ClaimsIdentity identity = new ClaimsIdentity("AuthenticationTypes.Federation");
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_USERID, value: user.Id.ToString()));
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_ACCOUNT, value: user.Account));
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_NAME, value: user.Name));
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_SUPERADMIN, value: ((int)user.AdminType).ToString()));
identity.AddClaim(new Claim(type: ClaimConst.CLAINM_TENANT_TYPE, value: tenant.TenantType.ToString()));
identity.AddClaim(new Claim(type: ClaimConst.TENANT_ID, value: tenant.Id.ToString()));
identity.AddClaim(new Claim(type: ClaimConst.TENANT_NAME, value: tenant.Name));
identity.AddClaim(new Claim(type: ClaimConst.DjyCompanyId, value: tenant.CompId == null ? string.Empty : tenant.CompId));
identity.AddClaim(new Claim(type: ClaimConst.DjyUserId, value: user.DjyUserId));
ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity);
httpContext.User = claimsPrincipal;
return next();
}
}
throw Oops.Oh("无权调用!请检查授权或联系管理员。");
}
return next();
}
}
}