ошибка :

я есть приложение net core 2.0 и проблема с авторизацией. Я хочу использовать пользовательскую авторизацию со специальным request.header и стандартной аутентификацией по умолчанию. Сначала я добавляю конфигурацию в 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()

Если я использую неправильный request.header в AuthTokenPolicy, я вижу это. Но в логах вижу ошибку:

System.InvalidOperationException: не указана схема authenticationScheme, и не было найдено DefaultChallengeScheme. \ R \ n в Microsoft.AspNetCore.Authentication.AuthenticationService.d__11.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, где произошла исключительная ситуация было брошено --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) \ r \ n в Microsoft.AspNetCore.Mvc. ChallengeResult.d__14.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего местоположения, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в системе .Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) \ r \ n в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__19.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, где было выброшено исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ na t System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) \ r \ n в Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.d__17.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, где исключение было брошено --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (задача задачи) \ r \ n в Microsoft.AspNetCore.Mvc. Internal.ResourceInvoker.d__15.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего местоположения, в котором было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) \ r \ n в Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, где было выброшено исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerSe rvices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) \ r \ n в Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.d__3.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, в котором было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Задача) \ r \ n в React.AspNet.BabelFileMiddleware___ () \ n --- Конец трассировки стека из предыдущего местоположения, где было сгенерировано исключение --- \ r \ n в System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification ( Задача) \ r \ n в Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.d__6.MoveNext () \ r \ n --- Конец трассировки стека из предыдущего расположения, где было сгенерировано исключение --- \ r \ n в System.Runtime .ExceptionServices.ExceptionDispatchInfo.Throw () \ r \ n в System.Runtime.CompilerServices.TaskAwaiter.Han dleNonSuccessAndDebuggerNotification (Задача) \ r \ n на core.common.Middleware.LoggingMiddleware.d__3.MoveNext () в D: \ Dev \ microservicePDP \ Template \ core.common \ Middleware \ LoggingMiddleware.cs: строка 72

После прочтенияМиграция аутентификации и идентификации в ASP.NET Core 2.0 Я добавил этот код в startup.cs

Цитата из статьи:

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

Определите схему по умолчанию в 2.0, если выполняется одно из следующих условий: Вы хотите, чтобы пользователь автоматически входил в систему. Вы используете атрибут [Authorize] или политики авторизации без указания схем

Я добавил AuthenticationScheme и DefaultChallengeScheme в ConfigureServices. Это не помогло, та же ошибка здесь. Я попытался использовать app.UseAuthentication (); в Configure в StartUp.cs результатов нет. Может кто-нибудь объяснить, как использовать пользовательскую авторизацию без аутентификации?

 Galina05 дек. 2017 г., 08:58
Да. Не правильно?
 Neville Nazerane05 дек. 2017 г., 10:03
Я просто подтверждаю то, что вы написали. Я предполагаюDefaultChallengeScheme устанавливается только для политики авторизации по умолчанию .... в любом случае попробуйте мой ответ
 Neville Nazerane03 дек. 2017 г., 19:55
так после использованияAddAuthentication, ты опять использовал[Authorize(Policy = Startup.DefaultAuthorizedPolicy)] ?

Ответы на вопрос(5)

и вдруг ваше приложение не запускается с сообщением об ошибке, описанным ниже, то для меня сработала отмена «Включить ссылку браузера»

снимите этот флажок

ошибка :

Conversion> [13:31:10 ERR] Connection id "0HLJ153E20LDJ", Request id "0HLJ153E20LDJ:00000003": An unhandled exception was thrown by the application.
Conversion> System.ObjectDisposedException: The response has been aborted due to an unhandled application exception. ---> System.FormatException: Invalid ETag name
Conversion>    at Microsoft.Net.Http.Headers.EntityTagHeaderValue..ctor(StringSegment tag, Boolean isWeak)
Conversion>    at Microsoft.Net.Http.Headers.EntityTagHeaderValue..ctor(StringSegment tag)
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleWareUtil.AddToETag(ResponseHeaders responseHeader, Int32 port)
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware.<>c__DisplayClass7_0.<ExecuteWithFilter>b__0()
Conversion>    at Microsoft.AspNetCore.Http.HttpResponse.<>c.<.cctor>b__30_0(Object callback)
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FireOnStartingMayAwait(Stack`1 onStarting)
Conversion>    --- End of inner exception stack trace ---
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ThrowResponseAbortedException()
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount)
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WriteAsync(ReadOnlyMemory`1 data, CancellationToken cancellationToken)
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
Conversion>    at System.IO.Stream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count)
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.ScriptInjectionFilterStream.<>c__DisplayClass37_0.<<CreateResponseHandler>b__0>d.MoveNext()
Conversion> --- End of stack trace from previous location where exception was thrown ---
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.SocketReader.ReadBytesIntoResponseHandler(Int64 totalBytesToRead, ResponseHandler handler, CancellationToken cancellationToken)
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.HttpSocketAdapter.ResponseReader.ReadBytesIntoResponse(Int64 bytesToRead)
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.HttpSocketAdapter.ResponseReader.ReadChunkedContent()
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.HttpSocketAdapter.ResponseReader.ReadResponse()
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.DelayConnectingHttpSocketAdapter.Microsoft.VisualStudio.Web.BrowserLink.IHttpSocketAdapter.WaitForResponseComplete()
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.ScriptInjectionFilterStream.WaitForFilterComplete()
Conversion>    at Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware.ExecuteWithFilter(IHttpSocketAdapter injectScriptSocket, String requestId, HttpContext httpContext)
Conversion>    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Conversion>    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Conversion>    at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
Conversion>    at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

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

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

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

 Galina08 дек. 2017 г., 09:43
Привет. Я добавил AddAuthentication (). AddCookie () и policy.AuthenticationSchemes, и после этого у меня есть статус 200 Ok с правильным токеном и 404 с неправильным токеном. Я отладил код и увидел статус = 401 в методе в TokenAuthPolicy.HandleRequirementAsync, но клиент получил 404. Есть ли у вас какие-либо идеи, где net core меняет статус с 401 на 404?
 Neville Nazerane06 дек. 2017 г., 17:58
да уж. вам нужно добавить кукиAddAuthentication().AddCookie()
 Neville Nazerane08 дек. 2017 г., 19:36
если вы используете токены, вы можете попробовать.AddJTW() также.
 Galina06 дек. 2017 г., 16:18
Только что попробовал, исключение сложно: «Не настроен обработчик аутентификации для аутентификации для схемы: Cookies». Я предпочитаю не писать собственные cookie-аутентификации и не могу найти что-то полезное для нового исключения.
Решение Вопроса

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

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

И 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";
}}
 Victor.Uduak15 сент. 2018 г., 15:43
Откуда класс TokenAuthenticationOptions? Вы сами это определили или это из библиотеки?
 Galina19 сент. 2018 г., 09:11
Привет. Я обновил первый комментарий, он был определен в статическом классе. У меня тут не такой же, но очень похожий проектgithub.com/galenam/MicroserviceTemplate
 user153220818 сент. 2018 г., 16:44
Где определен SchemesNamesConst?
 Galina17 сент. 2018 г., 08:50
Привет. Я не могу найти TokenAuthenticationOptions сейчас, но он был пуст. Я нашел тот же класс PhoneNumberAuthenticationOptions и добавил его в первый комментарий

Хотя ваше новое решение может достичь вашей первоначальной цели, все еще возможно обойти исходную ошибку, сохранив логику AuthorizationHandler--при условии у вас есть обработчики базовой схемы аутентификации, даже если они функционально являются скелетами.

Говоря в широком смысле, обработчики и схемы аутентификации предназначены для установления + проверки идентичности, что делает их необходимыми для работы обработчиков / политик авторизации, поскольку они работают на предположении, что идентичность уже установлена.

ASP.NET Dev Haok суммирует это лучшее здесь: «Аутентификация сегодня вообще не знает об авторизации, она только заботится о создании ClaimsPrincipal для каждой схемы. Авторизация должна быть в некоторой степени осведомлена об аутентификации, поэтому AuthenticationSchemes в политике - это механизм чтобы вы связали политику со схемами, используемыми для построения эффективного участника заявок для авторизации (или он просто использует для запроса httpContext.User по умолчанию, который полагается на DefaultAuthenticateScheme). "https://github.com/aspnet/Security/issues/1469

В моем случае решение, над которым я работаю, имело собственную неявную концепцию идентификации, поэтому нам не нужны были схемы / обработчики аутентификации - только маркеры заголовков для авторизации. Таким образом, пока наши концепции идентичности не изменятся, наши обработчики авторизации токена заголовка, которые применяют политики, могут быть привязаны к скелетам схемы 1 к 1.

Теги на конечных точках:

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

Оба пустой обработчик аутентификацииа также вызывается обработчик авторизации (аналогично настройке соответствующих публикаций OP), но обработчик авторизации все еще обеспечивает соблюдение наших политик авторизации.

это сработало для меня

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,
        options =>
        {
            options.LoginPath = new PathString("/auth/login");
            options.AccessDeniedPath = new PathString("/auth/denied");
        });

Ваш ответ на вопрос