Tidak ada authenticationScheme yang ditentukan, dan tidak ada DefaultChallengeScheme yang ditemukan dengan otentifikasi default dan otorisasi kustom.

Nov 16 2017

Saya memiliki aplikasi .NET Core 2.0 dan bermasalah dengan otorisasi. Saya ingin menggunakan otorisasi khusus dengan permintaan khusus. Header dan otentikasi default standar. Pertama, saya menambahkan konfigurasi di 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;
    }
}

dan di HomeController.cs:

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

Jika saya menggunakan request.header yang salah di AuthTokenPolicysaya melihatnya, tetapi di log saya melihat kesalahan ini:

System.InvalidOperationException: Tidak ada authenticationScheme yang ditentukan, dan tidak ada DefaultChallengeScheme yang ditemukan. \ R \ n di Microsoft.AspNetCore.Authentication.AuthenticationService.d__11.MoveNext () \ r \ n --- Akhir pelacakan tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Mvc. ChallengeResult.d__14.MoveNext () \ r \ n --- Akhir pelacakan tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di Sistem .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__19.MoveNext () \ r \ n --- Akhir pelacakan tumpukan dari lokasi sebelumnya tempat pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ na t System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext () \ r \ n --- Akhir jejak tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Mvc. Internal.ResourceInvoker.d__15.MoveNext () \ r \ n --- Akhir jejak tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext () \ r \ n --- Akhir dari pelacakan tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerSe rvices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.d__3.MoveNext () \ r \ n --- Akhir pelacakan tumpukan dari lokasi sebelumnya tempat pengecualian dilempar --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di React.AspNet.BabelFileMiddleware.d__5.MoveNext \ n --- Akhir pelacakan tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification ( Tugas tugas) \ r \ n di Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext () \ r \ n --- Akhir jejak tumpukan dari lokasi sebelumnya di mana pengecualian dilemparkan --- \ r \ n di System.Runtime .ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n di System.Runtime.CompilerServices.TaskAwaiter.Han dleNonSuccessAndDebuggerNotification (Tugas tugas) \ r \ n di core.common.Middleware.LoggingMiddleware.d__3.MoveNext () di D: \ Dev \ microservicePDP \ Template \ core.common \ Middleware \ LoggingMiddleware.cs: baris 72

Setelah membaca Migrating Authentication and Identity to ASP.NET Core 2.0, saya telah menambahkan kode ini di startup.cs

Kutipan dari artikel:

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

Tentukan skema default di 2.0 jika salah satu dari kondisi berikut ini benar: Anda ingin pengguna masuk secara otomatis Anda menggunakan atribut [Otorisasi] atau kebijakan otorisasi tanpa menentukan skema

Saya menambahkan AuthenticationSchemedan DefaultChallengeSchememasuk ConfigureServices(). Itu tidak membantu, kesalahan yang sama di sini. Saya sudah mencoba untuk menggunakan app.UseAuthentication();dalam Startup.Configure()metode, tanpa hasil.

Bagaimana saya bisa menggunakan otorisasi kustom tanpa otentikasi?

Jawaban

30 Galina Feb 21 2018 at 17:06

Jangan gunakan otorisasi sebagai ganti otentikasi. Saya harus mendapatkan akses penuh untuk melayani semua klien dengan header. Kode kerja adalah:

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

Dan mycontroller.cs

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

Saya tidak dapat menemukan TokenAuthenticationOptions sekarang, tapi kosong. Saya menemukan kelas yang sama PhoneNumberAuthenticationOptions:

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

Anda harus mendefinisikan kelas statis SchemesNamesConst. Sesuatu seperti:

public static class SchemesNamesConst
{
    public const string TokenAuthenticationDefaultScheme = "TokenAuthenticationScheme";
}
28 alizarei Jan 11 2019 at 14:02

ini berhasil untuk saya

// 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");
        });
4 NevilleNazerane Dec 04 2017 at 02:11

Ketika saya menggunakan kebijakan sebelumnya, saya juga menetapkan skema otentikasi default ke dalamnya. Saya telah memodifikasi DefaultPolicyjadi sedikit berbeda. Namun hal yang sama juga harus berfungsi untuk kebijakan tambahan.

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

Pertimbangkan bahwa AuthenticationSchemesproperti default menggunakan daftar hanya baca. Saya pikir akan lebih baik untuk mengimplementasikannya daripada List juga.

2 DaganDanevic Nov 05 2018 at 13:27

Pernyataan awal Anda dalam solusi yang ditandai tidak sepenuhnya benar. Meskipun solusi baru Anda dapat mencapai tujuan awal Anda, masih mungkin untuk menghindari kesalahan asli sambil mempertahankan logika AuthorizationHandler Anda - asalkan Anda memiliki penangan skema otentikasi dasar, bahkan jika mereka berfungsi sebagai kerangka.

Berbicara secara luas, Authentication Handler dan skema dimaksudkan untuk menetapkan + memvalidasi identitas, yang membuatnya diperlukan agar Otorisasi Penangan / kebijakan berfungsi - karena mereka berjalan dengan anggapan bahwa identitas telah ditetapkan.

ASP.NET Dev Haok merangkum terbaik ini di sini: "Otentikasi saat ini tidak mengetahui otorisasi sama sekali, hanya peduli tentang menghasilkan ClaimsPrincipal per skema. Otorisasi harus agak mengetahui otentikasi, jadi AuthenticationSchemes dalam kebijakan adalah mekanisme bagi Anda untuk mengaitkan kebijakan dengan skema yang digunakan untuk membuat prinsip klaim yang efektif untuk otorisasi (atau hanya menggunakan httpContext.User default untuk permintaan tersebut, yang bergantung pada DefaultAuthenticateScheme). " https://github.com/aspnet/Security/issues/1469

Dalam kasus saya, solusi yang saya kerjakan memberikan konsep identitas implisitnya sendiri, jadi kami tidak memerlukan skema / penangan otentikasi - hanya token header untuk otorisasi. Jadi hingga konsep identitas kami berubah, penangan otorisasi token tajuk kami yang menerapkan kebijakan dapat dikaitkan dengan kerangka skema 1-ke-1.

Tag di titik akhir:

[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>();

Baik penangan otentikasi kosong dan penangan otorisasi dipanggil (serupa dalam penyiapan untuk masing-masing pos OP) tetapi penangan otorisasi masih memberlakukan kebijakan otorisasi kami.