我正在开发一个Web-api,该API对我们的另一个应用程序使用某种授权,以验证用户仍在登录并且可以继续执行他们所请求的操作。但是,当用户未通过身份验证时,服务器将响应500内部服务器错误,可以在下面找到堆栈跟踪。 我似乎无法使配置进入正确的状态。从堆栈跟踪中,我可以看出它尝试回退到一些默认的身份验证方案,该方案尚未定义,理想情况下不感兴趣,因为我们一直希望对第三方进行授权,如果返回第三方,则只会失败错误。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IAuthService>(_ =>
new AuthService(damInfo.BaseUrl, damInfo.SystemUsername, damInfo.SystemPassword));
services.AddScoped<IAuthorizationHandler, AuthenticationHandler>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddAuthorization(options =>
{
options.AddPolicy("ServicePolicy", policy =>
policy.Requirements.Add(new ServiceRequirement("")));
/*options.DefaultPolicy = new AuthorizationPolicyBuilder().AddAuthenticationSchemes(Constants.NoOp).RequireAuthenticatedUser().Build(); // keep#1#*/
options.InvokeHandlersAfterFailure = false;
});
services.AddAuthentication(options =>
{
options.DefaultScheme = Constants.NoOp;
options.DefaultChallengeScheme = Constants.NoOp;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseHsts();
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
builder.AllowAnyOrigin();
});
app.UseHttpsRedirection();
app.UseMvc();
}
政策:
using Microsoft.AspNetCore.Authorization;
namespace Core.Services.Authentication
{
public class ServiceRequirement : IAuthorizationRequirement
{
public string CurrentToken { get; private set; }
public ServiceRequirement(string token)
{
CurrentToken = token;
}
}
}
授权属性:
[Authorize(Policy = "ServicePolicy")]
身份验证处理程序:
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Digizuite.Services.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
namespace Core.Services.Authentication
{
public class AuthenticationHandler : AuthorizationHandler<ServiceRequirement>
{
readonly IAuthService _authService;
/// <summary>
/// Authentication handler that check if user is logged in
/// </summary>
/// <param name="authService"></param>
public AuthenticationHandler(IAuthService authService)
{
_authService = authService;
}
/// <summary>
/// Handle requirement and check isLoggedIn
/// </summary>
/// <param name="context"></param>
/// <param name="requirement"></param>
/// <returns></returns>
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context,
ServiceRequirement requirement)
{
var authFilterCtx = (Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext)context.Resource;
var httpContext = authFilterCtx.HttpContext;
var headers = httpContext.Request.Headers[HeaderNames.Authorization];
if (StringValues.IsNullOrEmpty(headers) == true)
{
context.Fail();
}
else
{
var auth = AuthenticationHeaderValue.Parse(headers);
var loginResponse = _authService.IsLoggedInRequest(auth.Parameter).Result;
if (loginResponse.IsLoggedIn == false)
{
context.Fail();
}
else
{
context.Succeed(requirement);
}
}
}
}
}
StackTrace:
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HLOC48NR5MP4", Request id "0HLOC48NR5MP4:00000001": An unhandled exception was thrown by the application.
System.InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.
at Microsoft.AspNetCore.Authentication.AuthenticationService.ChallengeAsync(HttpContext context, String scheme, AuthenticationProperties properties)
at Microsoft.AspNetCore.Mvc.ChallengeResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAlwaysRunResultFilters()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Digizuite.Logging2.LogClient.LoggerRequestMiddleware.InvokeAsync(HttpContext context, RequestDelegate next) in C:\dev\digizuite.core\Libs\LogClient\LoggerRequestMiddleware.cs:line 40
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.<>c__DisplayClass5_1.<<UseMiddlewareInterface>b__1>d.MoveNext()