2017-10-25 123 views
6

Stworzyłem nowy projekt aplikacji sieci Web ASP.NET Core w VS17 przy użyciu szablonu "Szablon aplikacji sieci Web (model-widok-kontroler)" i ".Net Framework "+" ASP.NET Core 2 "jako konfiguracja. Konfiguracja uwierzytelniania jest ustawiona na "Indywidualne konta użytkowników".ASP.NET Core 2.0 łączący pliki cookie i autoryzację na okaziciela dla tego samego punktu końcowego

że ma następujący przykładowy punkt końcowy:

[Produces("application/json")] 
[Route("api/price")] 
[Authorize(Roles = "PriceViwer", AuthenticationSchemes = "Cookies,Bearer")] 
public class PriceController : Controller 
{ 

    public IActionResult Get() 
    { 
     return Ok(new Dictionary<string, string> { {"Galleon/Pound", 
                "999.999" }); 
    } 
} 

"Cookies,Bearer" powstaje przez łączenie CookieAuthenticationDefaults.AuthenticationScheme i JwtBearerDefaults.AuthenticationScheme.

Celem jest umożliwienie skonfigurowania autoryzacji dla punktu końcowego, aby umożliwić dostęp do niej przy użyciu zarówno metody uwierzytelniania tokenem, jak i cookie.

Oto konfiguracja mam uwierzytelniania w moich Startup.cs:

services.AddAuthentication() 
     .AddCookie(cfg => { cfg.SlidingExpiration = true;}) 
     .AddJwtBearer(cfg => { 
      cfg.RequireHttpsMetadata = false; 
      cfg.SaveToken = true; 
      cfg.TokenValidationParameters = new TokenValidationParameters() { 
                ValidIssuer = Configuration["Tokens:Issuer"], 
                ValidAudience = Configuration["Tokens:Issuer"], 
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])) 
               }; 
     }); 

Więc, gdy próbuję uzyskać dostęp do punktu końcowego przy użyciu przeglądarki, I get the 401 response with a blank html page.

Potem zalogować i gdy próbuję aby uzyskać dostęp do punktu końcowego, otrzymuję tę samą odpowiedź.

Następnie próbuję uzyskać dostęp do punktu końcowego, określając token na okaziciela. And that returns the desired result with the 200 response.

Tak więc, jeśli usunąć [Authorize(AuthenticationSchemes = "Cookies,Bearer")], sytuacja staje przeciwnie - prace uwierzytelniania cookies i zwraca 200, jednak taka sama metoda jak okaziciela żeton używany powyżej nie daje żadnych rezultatów i po prostu przekierować do domyślnej strony logowania AspIdentity .

można zobaczyć dwa możliwe problemy:

1) ASP.NET rdzeń nie pozwala na uwierzytelnianie scaloną. 2) "Pliki cookie" nie są poprawną nazwą schematu. Ale w takim razie, jaki jest właściwy do użycia?

Prosimy o radę. Dziękuję Ci.

+0

Czy używasz Idendity? – Nikolaus

+0

Używam tego samego pliku cookie i elementu nośnego w rdzeniu programu aspnet 1.0. Migracja do wersji 2.0 będzie miała ten sam problem :( – Ruchan

+0

Byłoby wspaniale, gdybyśmy nie musieli w ogóle wspominać o akcji "AuthenticationScheme". – Ruchan

Odpowiedz

3

Wydaje mi się, że nie trzeba ustawiać opcji AuthenticationScheme na kontrolerze. Wystarczy użyć uwierzytelniony użytkownik w ConfigureServices tak:

// requires: using Microsoft.AspNetCore.Authorization; 
//   using Microsoft.AspNetCore.Mvc.Authorization; 
services.AddMvc(config => 
{ 
    var policy = new AuthorizationPolicyBuilder() 
        .RequireAuthenticatedUser() 
        .Build(); 
    config.Filters.Add(new AuthorizeFilter(policy)); 
}); 

Dokumentacji moich źródeł: registerAuthorizationHandlers

dla części, czy system-Key nie było ważne, można użyć interpolowana ciąg, aby użyć odpowiednie klawisze:

[Authorize(AuthenticationSchemes = $"{CookieAuthenticationDefaults.AuthenticationScheme},{JwtBearerDefaults.AuthenticationScheme}")] 

Edit: zrobiłem dalszych badań i doszedł do następującego wniosku: To nie jest możliwe, aby zezwolić metodę z dwóch programów lub podobny, ale można korzystać z dwóch p Metody ublic, aby wywołać metodę prywatną, taką jak ta:

//private method 
private IActionResult GetThingPrivate() 
{ 
    //your Code here 
} 

//Jwt-Method 
[Authorize(AuthenticationSchemes = $"{JwtBearerDefaults.AuthenticationScheme}")] 
[HttpGet("bearer")] 
public IActionResult GetByBearer() 
{ 
    return GetThingsPrivate(); 
} 

//Cookie-Method 
[Authorize(AuthenticationSchemes = $"{CookieAuthenticationDefaults.AuthenticationScheme}")] 
[HttpGet("cookie")] 
public IActionResult GetByCookie() 
{ 
    return GetThingsPrivate(); 
} 
+0

Dziękuję odpowiedzi! Niestety, to nie rozwiąże problemu: jeśli użyję fragmentu kodu konfiguracji z Twojego komentarza i usuń AuthenticationScheme z dekoratora punktu końcowego, to działa standardowa metoda plików cookie, ale token nie działa. – maximiniini

+0

@maximiniini Czy próbowałeś odwrócić kolejność? Na przykład: "[Authorize (AuthenticationSchemes =" Bearer, Cookies ")]' – Nikolaus

+0

@maximiniini Zaktualizowałem swoją odpowiedź. Może to może ci pomóc. – Nikolaus