Маркер на предъявителя всегда возвращает 401 Несанкционированная ошибка - PullRequest
0 голосов
/ 16 апреля 2020

У меня все еще есть серьезная проблема, когда мой jwt 401 не авторизован на моих звонках. Я использую ядро ​​asp. net 3.1. net для создания слоя API.

1002 * Токен:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZha2VAZW1haWwuY29tIiwibmJmIjoxNTg3MDY3NTMyLCJleHAiOjE1ODcxNTM5MzIsImlhdCI6MTU4NzA2NzUzMn0.cwQRoRWGxIqfTWsFleJp8qUlCr7ovS4urr8kcvPoxpE

Это генерируется из следующих Стати c метод класса, который присоединен через мой класс запуска

public static class AuthenticationExtension {
        public static IServiceCollection AddTokenAuthentication(this IServiceCollection services, IConfiguration config) {
            var secret = config.GetSection("JwtConfig").GetSection("secret").Value;

            var key = Encoding.ASCII.GetBytes(secret);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false, 
                    ValidateAudience = false,
                    // ValidIssuer = "localhost",
                    //ValidAudience = "localhost"
                };
            });

            return services;
        }
    }

Json Настройки

"JwtConfig": {"secret": "PDv7DrqznYL6nv7DrqzjnQYO9JxIsWdcjnQYL6nu0f", 101 * 101 * мин.

Но когда я вызываю примерный контроллер погоды контроллером котельной пластины, я получаю 401 не авторизованным, даже несмотря на то, что прошел процесс отправки его в раздел аутентификации в почтальоне.

Мой пример погодного контроллера

[ApiController]
[Authorize]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
    }
}

enter image description here

Авторизованный attritube - это просто дополнительный слой, который я должен проверить на наличие идентификатора клиента и секретного идентификатора из базы данных.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ApiKeyAttribute : Attribute, IAsyncActionFilter {
    public string ApiKeyHeaderName = "ApiKey";
    public string ClientSecret = "ClientSecret";
    RoundTableERPContext db = new RoundTableERPContext();

    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) {
        //before
        if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var potentialApiKey)) {
            context.Result = new UnauthorizedResult();
            return;

        }

        // before
        if (!context.HttpContext.Request.Headers.TryGetValue(ClientSecret, out var potentialClientId)) {
            context.Result = new UnauthorizedResult();
            return;


        }
        Guid.TryParse(potentialApiKey, out Guid headerApiKey);
        Guid.TryParse(potentialClientId, out Guid headerClientId);
        if (!db.FindKeysByClientIdByApiKey(headerApiKey, headerClientId)) {
            context.Result = new UnauthorizedResult();
            return;
        }

        await next();
        //after

    }

Любые идеи, почему почтальон возвращается торизованный

Edit 1 Показать класс My Token о том, как токен генерируется.

[Route("api/[controller]")]
[ApiController]
public class TokenController : ControllerBase
{
    private IConfiguration _config;

    public TokenController(IConfiguration config)
    {
        _config = config;
    }

    [HttpGet]
    public string GetRandomToken()
    {
        var jwt = new JwtService(_config);
        var token = jwt.GenerateSecurityToken("fake@email.com");
        return token;
    }
}

}

Я считаю, что проблема может заключаться в делать с тем фактом, что учебник, которому я следовал, использовал fake@email.com

var token = jwt.GenerateSecurityToken ("fake@email.com");

Это говорит о недопустимой подписи, но не почему, когда я проверить это

1047 *
https://jwt.io/#debugger -io? лексема = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZha2VAZW1haWwuY29tIiwibmJmIjoxNTg3MDY3NTMyLCJleHAiOjE1ODcxNTM5MzIsImlhdCI6MTU4NzA2NzUzMn0.cwQRoRWGxIqfTWsFleJp8qUlCr7ovS4urr8kcvPoxpE
1052 * Это мой JwtService как он получает создан
 public class JwtService {
    private readonly string _secret;
    private readonly string _expDate;

    public JwtService(IConfiguration config) {
        _secret = config.GetSection("JwtConfig").GetSection("secret").Value;
        _expDate = config.GetSection("JwtConfig").GetSection("expirationInMinutes").Value;
    }

    public string GenerateSecurityToken(string email) {
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes(_secret);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(new[]
            {
                new Claim(ClaimTypes.Email, email)
            })
        ,
            Expires = DateTime.UtcNow.AddMinutes(double.Parse(_expDate)),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return tokenHandler.WriteToken(token);

    }

Редактировать 2 Как сказал Jps для тестирования, мне пришлось вставить свой секрет в секретное поле с правой стороны, теперь это проверено, но. net по-прежнему возвращает 401 неавторизованным.

https://jwt.io/#debugger -io? лексема = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImZha2VAZW1haWwuY29tIiwibmJmIjoxNTg3MDY3NTMyLCJleHAiOjE1ODcxNTM5MzIsImlhdCI6MTU4NzA2N zUzMn0.cwQRoRWGxIqfTWsFleJp8qUlCr7ovS4urr8kcvPoxpE

Редактировать 2 Здесь также находятся мои файлы конфигурации.

 public void ConfigureServices(IServiceCollection services) {
     services.AddTokenAuthentication(Configuration);

        services.AddControllers();
        services.Configure<ConnectionStringConfig>(Configuration);

        services.AddHttpClient("externalservice", c =>
        {
            // Assume this is an "external" service which requires an API KEY
            c.BaseAddress = new Uri("https://localhost:5001/");
        });


        services
            .AddControllersWithViews()
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

        services.AddControllers().AddJsonOptions(jsonOptions =>
            {
                jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
            })
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        // Enable the application to use bearer tokens to authenticate users


        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });

    }
}

Редактировать 3 * 72 * Это мой класс, который настраивает аутентификацию

public static IServiceCollection AddTokenAuthentication(this IServiceCollection services, IConfiguration config) {
            var secret = config.GetSection("JwtConfig").GetSection("secret").Value;
            var keySecret = Base64UrlEncoder.DecodeBytes(secret);

            var key = Encoding.ASCII.GetBytes(keySecret.ToString());
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = false, 
                    ValidateAudience = false,
                    // ValidIssuer = "localhost",
                    //ValidAudience = "localhost"
                };
            });

            return services;
        }
    }

Редактировать 4

Отображение пост-человека 401 без подтверждения

enter image description here

Отображение отправленных заголовков

enter image description here

...