Skip to content

Commit e5a5cdb

Browse files
committed
feat: 新增授权异常处理器
1 parent 7e88c8a commit e5a5cdb

File tree

8 files changed

+135
-25
lines changed

8 files changed

+135
-25
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Bing.AspNetCore.ExceptionHandling
2+
{
3+
/// <summary>
4+
/// 授权异常处理器选项配置
5+
/// </summary>
6+
public class BingAuthorizationExceptionHandlerOptions
7+
{
8+
/// <summary>
9+
/// 认证方案
10+
/// </summary>
11+
public string AuthenticationScheme { get; set; }
12+
}
13+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Threading.Tasks;
2+
using Bing.Authorization;
3+
using Bing.DependencyInjection;
4+
using Bing.Exceptions;
5+
using Bing.Text;
6+
using Microsoft.AspNetCore.Authentication;
7+
using Microsoft.AspNetCore.Http;
8+
using Microsoft.Extensions.DependencyInjection;
9+
using Microsoft.Extensions.Options;
10+
11+
namespace Bing.AspNetCore.ExceptionHandling
12+
{
13+
/// <summary>
14+
/// 授权异常处理器
15+
/// </summary>
16+
public class DefaultBingAuthorizationExceptionHandler : IBingAuthorizationExceptionHandler, ITransientDependency
17+
{
18+
/// <summary>
19+
/// 处理
20+
/// </summary>
21+
/// <param name="exception">授权异常</param>
22+
/// <param name="httpContext">Http上下文</param>
23+
public virtual async Task HandleAsync(BingAuthorizationException exception, HttpContext httpContext)
24+
{
25+
var handlerOptions = httpContext.RequestServices
26+
.GetRequiredService<IOptions<BingAuthorizationExceptionHandlerOptions>>().Value;
27+
var isAuthenticated = httpContext.User.Identity?.IsAuthenticated ?? false;
28+
var authenticationSchemeProvider =
29+
httpContext.RequestServices.GetRequiredService<IAuthenticationSchemeProvider>();
30+
31+
AuthenticationScheme scheme = null;
32+
if (!handlerOptions.AuthenticationScheme.IsNullOrWhiteSpace())
33+
{
34+
scheme = await authenticationSchemeProvider.GetSchemeAsync(handlerOptions.AuthenticationScheme);
35+
if (scheme == null)
36+
throw new Warning($"No authentication scheme named {handlerOptions.AuthenticationScheme} was found.");
37+
}
38+
else
39+
{
40+
if (isAuthenticated)
41+
{
42+
scheme = await authenticationSchemeProvider.GetDefaultForbidSchemeAsync();
43+
if (scheme == null)
44+
throw new Warning($"There was no DefaultForbidScheme found.");
45+
}
46+
else
47+
{
48+
scheme = await authenticationSchemeProvider.GetDefaultChallengeSchemeAsync();
49+
if (scheme == null)
50+
throw new Warning($"There was no DefaultForbidScheme found.");
51+
}
52+
}
53+
54+
var handlers = httpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
55+
var handler = await handlers.GetHandlerAsync(httpContext, scheme.Name);
56+
if (handler == null)
57+
throw new Warning($"No handler of {scheme.Name} was found.");
58+
if (isAuthenticated)
59+
await handler.ForbidAsync(null);
60+
else
61+
await handler.ChallengeAsync(null);
62+
}
63+
}
64+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using System.Threading.Tasks;
5+
using Bing.Authorization;
6+
using Microsoft.AspNetCore.Http;
7+
8+
namespace Bing.AspNetCore.ExceptionHandling
9+
{
10+
/// <summary>
11+
/// 授权异常处理器
12+
/// </summary>
13+
public interface IBingAuthorizationExceptionHandler
14+
{
15+
/// <summary>
16+
/// 处理
17+
/// </summary>
18+
/// <param name="exception">授权异常</param>
19+
/// <param name="httpContext">Http上下文</param>
20+
Task HandleAsync(BingAuthorizationException exception, HttpContext httpContext);
21+
}
22+
}

framework/src/Bing.AspNetCore/Bing/AspNetCore/Extensions/Extensions.ServiceCollection.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using Bing.AspNetCore.Mvc;
22
using Bing.AspNetCore.Uploads;
3-
using Microsoft.AspNetCore.Hosting;
43
using Microsoft.Extensions.DependencyInjection;
54
using Microsoft.Extensions.DependencyInjection.Extensions;
65

@@ -37,20 +36,5 @@ public static class BingServiceCollectionExtensions
3736
/// <param name="services">服务集合</param>
3837
public static void AddApiInterfaceService<TApiInterfaceService>(this IServiceCollection services) where TApiInterfaceService : class, IApiInterfaceService =>
3938
services.TryAddSingleton<IApiInterfaceService, TApiInterfaceService>();
40-
41-
#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0
42-
/// <summary>
43-
/// 获取<see cref="IWebHostEnvironment"/>环境信息
44-
/// </summary>
45-
/// <param name="services">服务集合</param>
46-
public static IWebHostEnvironment GetWebHostEnvironment(this IServiceCollection services) => services.GetSingletonInstance<IWebHostEnvironment>();
47-
#elif NETSTANDARD2_0
48-
/// <summary>
49-
/// 获取<see cref="IHostingEnvironment"/>环境信息
50-
/// </summary>
51-
/// <param name="services">服务集合</param>
52-
public static IHostingEnvironment GetHostingEnvironment(this IServiceCollection services) => services.GetSingletonInstance<IHostingEnvironment>();
53-
#endif
54-
5539
}
5640
}

framework/src/Bing.AspNetCore/Bing/AspNetCore/Security/Claims/BingClaimsMapMiddleware.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,7 @@ public class BingClaimsMapMiddleware : IMiddleware
2222
/// 初始化一个<see cref="BingClaimsMapMiddleware"/>类型的实例
2323
/// </summary>
2424
/// <param name="next">方法</param>
25-
public BingClaimsMapMiddleware(RequestDelegate next)
26-
{
27-
_next = next;
28-
}
25+
public BingClaimsMapMiddleware(RequestDelegate next) => _next = next;
2926

3027
/// <summary>
3128
/// 执行中间件拦截逻辑

framework/src/Bing.AspNetCore/Bing/AspNetCore/Tracing/BingCorrelationIdMiddleware.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public async Task InvokeAsync(HttpContext context)
4646
{
4747
var correlationId = _correlationIdProvider.Get();
4848
TraceIdContext.Current ??= new TraceIdContext(correlationId);
49-
CheckAndSetCorrelationIdOnResponse(context, _options, correlationId);
5049
try
5150
{
5251
await _next(context);

framework/src/Bing.AspNetCore/Microsoft/AspNetCore/Http/BingHttpRequestExtensions.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Bing.Helpers;
1+
using System;
2+
using Bing.Helpers;
3+
using Microsoft.Net.Http.Headers;
24

35
namespace Microsoft.AspNetCore.Http
46
{
@@ -10,7 +12,7 @@ public static class BingHttpRequestExtensions
1012
/// <summary>
1113
/// 请求头:X-Requested-With
1214
/// </summary>
13-
private const string RequestedWithHeader = "X-Requested-With";
15+
private const string XRequestedWith = "X-Requested-With";
1416

1517
/// <summary>
1618
/// 请求头值:XMLHttpRequest
@@ -26,7 +28,8 @@ public static bool IsAjax(this HttpRequest request)
2628
Check.NotNull(request, nameof(request));
2729
if (request.Headers == null)
2830
return false;
29-
return request.Headers[RequestedWithHeader] == XmlHttpRequest;
31+
return string.Equals(request.Query[XRequestedWith], XmlHttpRequest, StringComparison.Ordinal) ||
32+
string.Equals(request.Headers[XRequestedWith], XmlHttpRequest, StringComparison.Ordinal);
3033
}
3134

3235
/// <summary>
@@ -38,7 +41,11 @@ public static bool CanAccept(this HttpRequest request, string contentType)
3841
{
3942
Check.NotNull(request, nameof(request));
4043
Check.NotNull(contentType, nameof(contentType));
41-
return request.Headers["Accept"].ToString().Contains(contentType);
44+
#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0
45+
return request.Headers[HeaderNames.Accept].ToString().Contains(contentType, StringComparison.OrdinalIgnoreCase);
46+
#elif NETSTANDARD2_0
47+
return request.Headers[HeaderNames.Accept].ToString().Contains(contentType);
48+
#endif
4249
}
4350
}
4451
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Microsoft.AspNetCore.Hosting;
2+
3+
namespace Microsoft.Extensions.DependencyInjection
4+
{
5+
/// <summary>
6+
/// 服务集合(<see cref="IServiceCollection"/>) 扩展
7+
/// </summary>
8+
public static class BingAspNetCoreServiceCollectionExtensions
9+
{
10+
#if NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0
11+
/// <summary>
12+
/// 获取<see cref="IWebHostEnvironment"/>环境信息
13+
/// </summary>
14+
/// <param name="services">服务集合</param>
15+
public static IWebHostEnvironment GetWebHostEnvironment(this IServiceCollection services) => services.GetSingletonInstance<IWebHostEnvironment>();
16+
#elif NETSTANDARD2_0
17+
/// <summary>
18+
/// 获取<see cref="IHostingEnvironment"/>环境信息
19+
/// </summary>
20+
/// <param name="services">服务集合</param>
21+
public static IHostingEnvironment GetHostingEnvironment(this IServiceCollection services) => services.GetSingletonInstance<IHostingEnvironment>();
22+
#endif
23+
}
24+
}

0 commit comments

Comments
 (0)