123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- using Microsoft.AspNetCore.Authentication;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Builder;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Http.Features;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- using System;
- using System.Net.Http.Headers;
- using System.Security.Claims;
- using System.Text.Encodings.Web;
- using System.Threading.Tasks;
- using XYY.Common.Standard;
- using XYY.Core.Standard.Data.Infrastructure;
- using XYY.Model.Standard;
- using XYY.Service.Standard.UserService;
- namespace XYY.Authentication.Standard
- {
- public static class BasicAuthenticationScheme
- {
- public const string DefaultScheme = "Basic";
- }
- public class BasicAuthenticationOption : AuthenticationSchemeOptions
- {
- }
- /// <summary>
- /// API服务中间证
- /// 认证token
- /// </summary>
- public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOption>
- {
- private readonly BasicAuthenticationOption authOptions;
- private readonly IUserService userService;
- private readonly IUnitOfWork unitOfWork;
- public BasicAuthenticationHandler(
- IOptionsMonitor<BasicAuthenticationOption> options,
- ILoggerFactory logger,
- UrlEncoder encoder,
- ISystemClock clock,
- IUserService userService,
- IUnitOfWork unitOfWork)
- : base(options, logger, encoder, clock)
- {
- authOptions = options.CurrentValue;
- this.userService = userService;
- this.unitOfWork = unitOfWork;
- }
- public Endpoint GetEndpoint(HttpContext context)
- {
- if (context == null)
- {
- return null;
- }
- return context.Features.Get<IEndpointFeature>()?.Endpoint;
- }
- /// <summary>
- /// 认证 Token
- /// </summary>
- /// <returns></returns>
- protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
- {
- bool isAllow = false;
- var endpoint = GetEndpoint(this.Context);
- if (endpoint != null)
- {
- var allow = endpoint.Metadata.GetMetadata<IAllowAnonymous>();
- if (allow != null)
- {
- isAllow = true;
- }
- }
- else
- {
- var claims = new[]
- {
- new Claim(ClaimTypes.StreetAddress,""),
- };
- var identity = new ClaimsIdentity(claims, Scheme.Name);
- var principal = new ClaimsPrincipal(identity);
- var ticket = new AuthenticationTicket(principal, Scheme.Name);
- unitOfWork.CurrentName = "";
- return await Task.FromResult(AuthenticateResult.Success(ticket));
- }
- if (isAllow || Request.Path.Value.Contains("dingtalk") || Request.Path.Value.Contains("SendNowCustomerQuotaion", StringComparison.InvariantCultureIgnoreCase))
- {
- var claims = new[]
- {
- new Claim(ClaimTypes.StreetAddress,""),
- };
- var identity = new ClaimsIdentity(claims, Scheme.Name);
- var principal = new ClaimsPrincipal(identity);
- var ticket = new AuthenticationTicket(principal, Scheme.Name);
- unitOfWork.CurrentName = "";
- return await Task.FromResult(AuthenticateResult.Success(ticket));
- }
- if (!Request.Headers.ContainsKey("Authorization"))
- {
- if (string.IsNullOrEmpty(Request.Query["access_token"]))
- {
- return AuthenticateResult.Fail("Missing Authorization ");
- }
- }
- try
- {
- string token = "";
- //var uservice = Context.RequestServices.GetService<IUserService>();
- if (Request.Headers.ContainsKey("Authorization"))
- {
- var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
- //var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
- if (!authHeader.Scheme.Equals("token", StringComparison.InvariantCultureIgnoreCase)
- && !authHeader.Scheme.Equals("bearer", StringComparison.InvariantCultureIgnoreCase))
- {
- return AuthenticateResult.Fail("Invalid Token");
- }
- else
- {
- token = authHeader.Parameter;
- }
- }
- else
- {
- token = Request.Query["access_token"];
- }
- var user = await Authorized(token);
- if (user != null)
- {
- ///当前用户的身份信息
- var claims = new[]
- {
- new Claim(ClaimTypes.StreetAddress,token),
- new Claim(ClaimTypes.NameIdentifier,user.Id.ToString()),
- new Claim(ClaimTypes.Name,user.NiceName),
- new Claim(ClaimTypes.GroupSid,user.CustomerId.ToString()),
- new Claim(ClaimTypes.Role,string.Join(",",user.Roles)),
- new Claim(ClaimTypes.AuthorizationDecision,string.Join(",",user.PrivilegeUrl))
- };
- var identity = new ClaimsIdentity(claims, Scheme.Name);
- var principal = new ClaimsPrincipal(identity);
- var ticket = new AuthenticationTicket(principal, Scheme.Name);
- unitOfWork.CurrentName = user.NiceName;
- return await Task.FromResult(AuthenticateResult.Success(ticket));
- }
- else
- {
- return AuthenticateResult.Fail("token无效");
- }
- }
- catch
- {
- return AuthenticateResult.Fail("Invalid Authorization Header");
- }
- }
- /// <summary>
- /// 质询
- /// </summary>
- /// <param name="properties"></param>
- /// <returns></returns>
- protected override async Task HandleChallengeAsync(AuthenticationProperties properties)
- {
- //Response.Headers["WWW-Authenticate"] = $"Basic realm=our site";
- await base.HandleChallengeAsync(properties);
- }
- /// <summary>
- /// 认证失败
- /// </summary>
- /// <param name="properties"></param>
- /// <returns></returns>
- protected override async Task HandleForbiddenAsync(AuthenticationProperties properties)
- {
- await base.HandleForbiddenAsync(properties);
- }
- private async Task<UserContent> Authorized(string token)
- {
- var ui = await userService.GetUserContentAtApi(token);
- return ui;
- }
- }
- public static class BasicAuthentication
- {
- public static void UseBasicAuthentication(this IApplicationBuilder app)
- {
- app.UseMiddleware<BasicAuthenticationMiddleware>();
- }
- }
- public class BasicAuthenticationMiddleware
- {
- private readonly RequestDelegate _next;
- private readonly ILogger _logger;
- public BasicAuthenticationMiddleware(RequestDelegate next, ILoggerFactory LoggerFactory)
- {
- _next = next;
- _logger = LoggerFactory.CreateLogger<BasicAuthenticationMiddleware>();
- }
- public async Task Invoke(HttpContext httpContext, IAuthenticationService authenticationService)
- {
- var authenticated = await authenticationService.AuthenticateAsync(httpContext, BasicAuthenticationScheme.DefaultScheme);
- //authenticated.Principal.Claims.
- //_logger.LogInformation("Access Status:" + authenticated.Succeeded);
- if (!authenticated.Succeeded)
- {
- await authenticationService.ForbidAsync(httpContext, BasicAuthenticationScheme.DefaultScheme, new AuthenticationProperties { });
- return;
- }
- await _next(httpContext);
- }
- }
- }
|