programing

authenticationScheme이 지정되지 않았으며 기본 인증 및 사용자 지정 권한 부여로 DefaultChallengeScheme을 찾을 수 없습니다.

powerit 2023. 4. 28. 21:46
반응형

authenticationScheme이 지정되지 않았으며 기본 인증 및 사용자 지정 권한 부여로 DefaultChallengeScheme을 찾을 수 없습니다.

저는 있습니다.NET Core 2.0 앱이며 인증에 문제가 있습니다.특별한 요청이 있는 사용자 지정 권한을 사용하고 싶습니다.헤더 및 표준 기본 인증입니다.먼저구추다니에 합니다.Startup.cs:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddAuthorization(options =>
    {
        options.AddPolicy(DefaultAuthorizedPolicy, policy =>
        {
            policy.Requirements.Add(new TokenAuthRequirement());
        });
    });
    services.AddSingleton<IAuthorizationHandler, AuthTokenPolicy>();
    // ...
}

AuthTokenPolicy.cs:

public class AuthTokenPolicy : AuthorizationHandler<TokenAuthRequirement>
{   
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TokenAuthRequirement requirement)
    {
        var filterContext = context.Resource as AuthorizationFilterContext;
        var response = filterContext.HttpContext.Response;
        try
        {
            // some validation code

            var isValidToken = isValidTokenTask.Result;
            if (!isValidToken)
            {
                response.StatusCode = 401;
                return Task.CompletedTask;
            }

            response.StatusCode = 200;
            context.Succeed(requirement);
        }
        catch (Exception)
        {
            return Task.CompletedTask;
        }
        return Task.CompletedTask;
    }
}

그고리로.HomeController.cs:

[Authorize(Policy = Startup.DefaultAuthorizedPolicy)]
public async Task<IActionResult> IsVisible()

만약 제가 잘못된 요청을 사용한다면요.헤딩인.AuthTokenPolicy표시되지만 로그에는 다음 오류가 표시됩니다.

System.잘못된 작동예외:authenticationScheme을 지정하지 않았으며 DefaultChallengeScheme을 찾을 수 없습니다.마이크로소프트에서 \r\n.AsNetCore.인증.인증 서비스.d__11.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.MVC.챌린지 결과.d__14.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.MVC.내부.리소스 호출기입니다.d__19.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.MVC.내부.ResourceInvoker.d_17입니다.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.MVC.내부.ResourceInvoker.d_15.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.빌더.라우터 미들웨어.d_4.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.진단.상태 코드 페이지Middleware.d_3.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.React에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNet.BabelFileMiddleware.d_5.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.Microsoft에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.AsNetCore.인증.인증 미들웨어.d_6.MoveNext()\r\n--- 시스템에서 예외가 발생한 이전 위치의 스택 추적 끝입니다.런타임.예외 서비스.예외 DispatchInfo입니다.시스템에()\r\n을 던집니다.런타임.컴파일러 서비스.작업 대기자입니다.core.common에서 NonSuccessAndDebugerNotification(작업 작업)\r\n을 처리합니다.미들웨어.로깅Middleware.d_3.D:에서 다음 이동():\Dev\microservicePDP\Template\core.common\Middleware\LoggingMiddleware.cs:line 72

ASP로 인증ID 마이그레이션을 읽은 후.NET Core 2.0 startup.cs 에 이 코드를 추가했습니다.

기사에서 인용한 내용:

services.AddAuthentication(options => 
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
});

다음 조건 중 하나에 해당하는 경우 2.0에서 기본 구성표를 정의합니다.사용자가 자동으로 로그인되도록 하려면 [Authorize] 특성 또는 권한 부여 정책을 사용합니다(스킴을 지정하지 않음).

추가했습니다.AuthenticationScheme그리고.DefaultChallengeSchemeConfigureServices()도움이 되지 않았습니다. 여기 같은 오류입니다.사용해 보았습니다.app.UseAuthentication();에 시대에Startup.Configure()메서드, 결과 없음.

인증 없이 사용자 지정 인증을 사용하려면 어떻게 해야 합니까?

인증 대신 인증을 사용하지 마십시오.나는 헤더로 모든 고객을 서비스할 수 있는 전체 액세스 권한을 가져야 합니다.

작동 코드는 다음과 같습니다.

public class TokenAuthenticationHandler : AuthenticationHandler<TokenAuthenticationOptions> 
{
    public IServiceProvider ServiceProvider { get; set; }

    public TokenAuthenticationHandler (IOptionsMonitor<TokenAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IServiceProvider serviceProvider) 
        : base (options, logger, encoder, clock) 
    {
        ServiceProvider = serviceProvider;
    }

    protected override Task<AuthenticateResult> HandleAuthenticateAsync () 
    {
        var headers = Request.Headers;
        var token = "X-Auth-Token".GetHeaderOrCookieValue (Request);

        if (string.IsNullOrEmpty (token)) {
            return Task.FromResult (AuthenticateResult.Fail ("Token is null"));
        }           

        bool isValidToken = false; // check token here

        if (!isValidToken) {
            return Task.FromResult (AuthenticateResult.Fail ($"Balancer not authorize token : for token={token}"));
        }

        var claims = new [] { new Claim ("token", token) };
        var identity = new ClaimsIdentity (claims, nameof (TokenAuthenticationHandler));
        var ticket = new AuthenticationTicket (new ClaimsPrincipal (identity), this.Scheme.Name);
        return Task.FromResult (AuthenticateResult.Success (ticket));
    }
}

Startup.cs :

#region Authentication
services.AddAuthentication (o => {
    o.DefaultScheme = SchemesNamesConst.TokenAuthenticationDefaultScheme;
})
.AddScheme<TokenAuthenticationOptions, TokenAuthenticationHandler> (SchemesNamesConst.TokenAuthenticationDefaultScheme, o => { });
#endregion

그리고 mycontroller.cs :

[Authorize(AuthenticationSchemes = SchemesNamesConst.TokenAuthenticationDefaultScheme)]
public class MainController : BaseController
{ ... }

지금 Token Authentication Options를 찾을 수 없지만 비어 있습니다.같은 클래스의 전화 번호를 찾았습니다.인증 옵션:

public class PhoneNumberAuthenticationOptions : AuthenticationSchemeOptions
{
    public Regex PhoneMask { get; set; }// = new Regex("7\\d{10}");
}

class 를 .SchemesNamesConst다음과 같은 것:

public static class SchemesNamesConst
{
    public const string TokenAuthenticationDefaultScheme = "TokenAuthenticationScheme";
}

이것은 나에게 효과가 있었습니다.

// using Microsoft.AspNetCore.Authentication.Cookies;
// using Microsoft.AspNetCore.Http;

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
        options =>
        {
            options.LoginPath = new PathString("/auth/login");
            options.AccessDeniedPath = new PathString("/auth/denied");
        });

인증 없이 AuthorizationHandler를 사용하려고 시도한 후 이 질문에 도달했습니다.정책을 기반으로 captcha를 자동으로 확인하여 captcha로 보호해야 하는 모든 엔드포인트에 정책을 적용하려고 했습니다.

나는 캡차가 검증되지 않으면 401이나 403을 던지고 싶을 때도 같은 실패로 끝났습니다.

저는 여기 있는 솔루션 중 어떤 것도 좋아하지 않습니다. 왜냐하면 그들은 우리가 실제로 아무것도 하지 않을 때 인증과 권한을 사용하려고 하기 때문입니다. 결국 ASP.NET Core는 Authorization과 Authentication을 연결합니다. 왜냐하면 설계 원칙상 그 사람이 누구인지 모르면 누군가가 권한을 부여받았는지 결정할 수 없기 때문입니다.

이를 통해 (요구 사항에 따라) 때때로 리소스 필터를 사용하여 인증/권한 부여 시스템을 그대로 두고 독립적으로 작동하도록 권한 부여 필터를 해킹할 수 있습니다.

솔루션은 모든 사용자에게 적합하지는 않지만, 저와 같은 사용자는 인증이 필요하지 않고 엔드포인트를 사용하는 사용자의 ID가 아닌 다른 항목을 기반으로 컨트롤러에 액세스할 수 있는지 여부를 결정하는 데 도움이 될 수 있습니다.

public class YourResourceFilter : IAsyncResourceFilter
{
    //any services you might need through DI (dependency injection)
    private readonly ICaptchaService captchaService;
    public YourResourceFilter(ICaptchaService captchaService)
    {
        this.captchaService = captchaService;
    }
    //this is where you need to code any logic related to your requirements.
    public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
    {
        //in my case I needed to get a header value, and verify it using my captcha service.
        //but you should be able to do almost anything here because you have access to DI.
        if (context.HttpContext.Request.Headers.TryGetValue("captcha", out var values))
        {
            var response = values.FirstOrDefault();
            if (response != null && await captchaService.VerifyCaptchAsync(response))
            {
                await next(); //if all is OK then keep going.
                return;
            }
        }
        //if not then set the status code to whatever you want. In my case I wanted to return 403 when the captcha couldn't be verified.
        context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
    }
}

이제 컨트롤러에서 이 필터를 어떻게 실행합니까?자원에 대한 의존성 주입은 어떻게 사용합니까?

다음과 같이 ServiceFilterAttribute를 상속하는 특성을 생성해야 합니다.

/// <summary>
/// This applies your own resource filter whenever you apply this attribute on a controller endpoint.
/// </summary>
public class YourResourceFilterAttribute : ServiceFilterAttribute
{
    public YourResourceFilterAttribute() : base(typeof(YourResourceFilter))
    {
    }
}

마지막으로 필터를 종속성 주입 컨테이너에 등록하는 것을 잊지 마십시오.

builder.Services.AddSingleton<YourResourceFilter>();

이 기능을 적용할 컨트롤러에 적용합니다.

[AllowAnonymous] //you can add this attribute is you want to bypass any authentication/authorization set up on that Asp.net core project, so you can use it no matter what configuration you have on the authentication/authorization system
[YourResourceFilter]
[HttpPost]
public Task ExampleAsync(CancellationToken cancellationToken = default)
{
    // whatever code your controller endpoint has
}

TL:DR:

사용IAsyncResourceFilter a 리고a.ServiceFilterAttribute사용자 지정 요청 논리를 적용하는 것은 위의 접근 방식보다 더 유연하고 덜 까다롭습니다.

  1. » IAsyncResourceFilter인증 없이 '권한 부여'에 대한 논리를 유지합니다.
  2. ServiceFilterAttribute를 상속하여 특성을 적용하는 컨트롤러에 필터를 적용하는 특성을 만듭니다.인증 여부와 상관없이 호환됩니다.하고자 할 에는 " " "/" " " " " " " " 을 .[AllowAnonymous]속성(있는 경우).
  3. 1.에서 생성된 필터를 종속성 주입 용기에 등록합니다.
  4. 2.에서 생성한 특성을 사용자 지정 논리를 적용할 컨트롤러 끝점에 추가합니다.

결론

이 접근 방식은 인증 기능을 해킹하는 것보다 훨씬 유연하게 작동합니다. 인증 기능이 제대로 설계되지 않은 경우에도 작동합니다.또한 인증/인가 시스템에 관계없이 작동할 수 있다는 장점이 있으므로 나중에 API에 추가하더라도 원하는 엔드포인트에서 이러한 매개 변수를 확인할 수 있습니다.IMO 이것은 결국 더 깨끗하고 간단한 접근법입니다.

기본 인증 체계를 정책에 설정하기 전에 정책을 사용한 경우.나는 그것을 수정했습니다.DefaultPolicy그래서 약간 달랐습니다.그러나 정책 추가에 대해서도 마찬가지입니다.

services.AddAuthorization(options =>
{
    options.AddPolicy(DefaultAuthorizedPolicy, policy =>
    {
        policy.Requirements.Add(new TokenAuthRequirement());
        policy.AuthenticationSchemes = new List<string>()
        {
            CookieAuthenticationDefaults.AuthenticationScheme
        }
    });
});

기본적으로 다음 사항을 고려합니다.AuthenticationSchemes속성에서 읽기 전용 목록을 사용합니다.저도 List 대신에 그것을 실행하는 것이 좋을 것 같습니다.

표시된 솔루션에 대한 당신의 초기 진술이 완전히 사실이 아닙니다.새 솔루션이 원래 목표를 달성할 수도 있지만 기본 인증 체계 처리기가 기능적으로 중요하더라도 AuthorizationHandler 논리를 유지하면서 원래 오류를 피할 수 있습니다.

일반적으로 인증 처리기 및 체계는 ID를 + 검증하기 위한 것으로, 인증 처리기/정책이 ID가 이미 설정되었다고 가정할 때 작동하는 데 필요합니다.

ASP.NET Dev Haok은 여기서 이를 가장 잘 요약합니다. "현재 인증은 인증에 대해 전혀 알지 못하며, 체계별로 클레임 프린서펄을 생성하는 데만 관심이 있습니다.인증은 인증에 대해 어느 정도 알고 있어야 하므로 정책의 AuthenticationScheme은 정책을 인증을 위한 유효 클레임 주체를 구축하는 데 사용되는 스키마와 연결하기 위한 메커니즘입니다(또는 기본 httpContext만 사용).기본값에 의존하는 요청에 대한 사용자AuthenticationScheme." https://github.com/aspnet/Security/issues/1469

저의 경우, 제가 연구하고 있는 솔루션은 자체적인 암묵적인 ID 개념을 제공했기 때문에 인증 체계/취급자가 필요하지 않았습니다. 단지 승인을 위한 헤더 토큰뿐이었습니다.따라서 ID 개념이 변경될 때까지 정책을 시행하는 헤더 토큰 권한 부여 처리기는 1 대 1 체계 골격과 연결될 수 있습니다.

엔드포인트의 태그:

[Authorize(AuthenticationSchemes = "AuthenticatedUserSchemeName", Policy = "AuthorizedUserPolicyName")]

Startup.cs :

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = "AuthenticatedUserSchemeName";
        }).AddScheme<ValidTokenAuthenticationSchemeOptions, ValidTokenAuthenticationHandler>("AuthenticatedUserSchemeName", _ => { });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("AuthorizedUserPolicyName", policy =>
            {
                //policy.RequireClaim(ClaimTypes.Sid,"authToken");
                policy.AddAuthenticationSchemes("AuthenticatedUserSchemeName");
                policy.AddRequirements(new ValidTokenAuthorizationRequirement());
            });
            services.AddSingleton<IAuthorizationHandler, ValidTokenAuthorizationHandler>();

빈 인증 처리기와 권한 부여 처리기를 모두 호출하지만(OP의 각 게시물과 유사한 설정) 권한 부여 처리기는 여전히 권한 부여 정책을 적용합니다.

언급URL : https://stackoverflow.com/questions/47324129/no-authenticationscheme-was-specified-and-there-was-no-defaultchallengescheme-f

반응형