ASP.NET Core API возвращает 401 при вызове от клиента React - PullRequest
0 голосов
/ 18 мая 2018

Я работаю над новым приложением ASP.NET Core 2.1 SPA с интерфейсом React / Redux.Я реализовал аутентификацию jwt, которая получает свой токен из Azure AD B2C.

Когда я анализирую вкладку сети для моего вызова API для серверной части, я вижу, что токен находится в заголовке - см. Ниже:

enter image description here

Вот код моего вызова извлечения:

import { fetchOptionsGet, fetchOptionsPost, parseJSON } from '../../utils/fetch/fetch-options';

export const getData = () => {

    return (dispatch) => fetch("/api/accounts/test", fetchOptionsGet())
        .then((response) => {

            if (response.ok) {

                parseJSON(response)
                    .then(result => {
                        // Do something here...
                    })
            }
        })
};

Вот мои варианты извлечения:

export const fetchOptionsGet = () => {

    const token = authentication.getAccessToken();
    debugger
    return {
        method: 'GET',
        mode: 'cors',
        headers: {
            "Content-Type": "application/json",
            "Authentication": "Bearer " + token
        }
    }
}

Обратите внимание на debugger в приведенном выше коде, чтобы убедиться, что я получаю токен, который подтверждает, что у меня есть токен - не говоря уже о том, что это мой сетевой вызов.

Вот ConfigureServices()метод в Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
        services.AddAuthentication(options => {
             options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
         })
         .AddJwtBearer(jwtOptions => {
         jwtOptions.Authority = $"https://login.microsoftonline.com/tfp/{Configuration["AzureAdB2C:Tenant"]}/{Configuration["AzureAdB2C:Policy"]}/v2.0/";
         jwtOptions.Audience = Configuration["AzureAdB2C:ClientId"];
         jwtOptions.Events = new JwtBearerEvents
         {
              OnAuthenticationFailed = AuthenticationFailed
         };
     });

     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

     // In production, the React files will be served from this directory
     services.AddSpaStaticFiles(configuration =>
     {
         configuration.RootPath = "ClientApp/build";
     });
}

Вот метод Configure() в Startup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
       app.UseDeveloperExceptionPage();
    }
    else
    {
       app.UseExceptionHandler("/Error");
       app.UseHsts();
    }

    app.UseHttpsRedirection();

    ScopeRead = Configuration["AzureAdB2C:ScopeRead"];
    app.UseAuthentication();

    app.UseStaticFiles();
    app.UseSpaStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller}/{action=Index}/{id?}");
    });

    app.UseSpa(spa =>
    {
        spa.Options.SourcePath = "ClientApp";

        if (env.IsDevelopment())
        {
           spa.UseReactDevelopmentServer(npmScript: "start");
        }
     });
}

Вот контроллер API:

[Produces("application/json")]
[Route("api/[controller]")]
[Authorize]
public class AccountsController : Controller
{
    [HttpGet("test")]
    public async Task<IActionResult> Test()
    {
        // Do something here...
    }
}

Iпоставить точку останова прямо в начале моего Test() метода API, но я его не использую.Без атрибута [Authorize] я могу использовать метод API Test() и получить свои данные.Итак, что-то в конвейере блокирует вызов еще до того, как я включил метод API.

Я также попытался указать схему авторизации в моем контроллере API с помощью следующего, но это не имело никакого значения.По-прежнему появляется ошибка 401.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

Есть идеи, где я здесь ошибаюсь?

1 Ответ

0 голосов
/ 19 мая 2018

Имя заголовка должно быть Authorization.

export const fetchOptionsGet = () => {

    const token = authentication.getAccessToken();
    debugger
    return {
        method: 'GET',
        mode: 'cors',
        headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + token //<--
        }
    }
}
...