Не было указано 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 я его вижу. Но в логах вижу ошибку:

2 ответов


Окей. Правильный ответ: Не используйте авторизацию вместо аутентификации. Я должен получить доступ к отверстию для обслуживания всех клиентов с коллектором. Рабочий код:

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));
    }
}

Автозагрузка.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
{ ...}

Я не могу найти TokenAuthenticationOptions сейчас, но он был пуст. Я нашел тот же класс PhoneNumberAuthenticationOptions:

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

}}

вы должны определить статический класс SchemesNamesConst Что-то например:

namespace Common.Const{
public static class SchemesNamesConst
{
    public const string SchemesNamesConst= "TokenAuthenticationScheme";
}}

когда я использовал политику, прежде чем я установил в нее схему аутентификации по умолчанию. Я изменил DefaultPolicy таким образом, это было немного по-другому. Однако то же самое должно работать и для политики add.

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

примите во внимание, что по умолчанию AuthenticationSchemes свойство использует список только для чтения. Я думаю, что было бы лучше реализовать это вместо списка.