首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AllowAnonymous跳过OpenIdDict 3.0

AllowAnonymous跳过OpenIdDict 3.0
EN

Stack Overflow用户
提问于 2020-05-11 22:25:34
回答 2查看 333关注 0票数 1

我使用的是OpenIdDict 3.0,它工作得很好,但是我有一个使用AllowAnonymous属性的控制器,而且我仍然收到“请求被拒绝,因为缺少访问令牌”。我假设这可能是与我的启动命令,这使它不会在管道中被击中,但我不确定。这是我的创业课:

代码语言:javascript
复制
 public async void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
        {
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();


            app.UseMvcWithDefaultRoute();
        }


 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(options =>
            {
                options.EnableEndpointRouting = false;
            }).AddNewtonsoftJson();

            services.AddAutoMapper(typeof(Startup));

            services.AddDbContext<MyDbContext>(options =>
            {
                options.UseSqlServer(WebConfig.ConnectionString, x => x.MigrationsAssembly("X.Api.DataAccess"));
                options.UseLazyLoadingProxies();
                options.UseOpenIddict();
            });

            services.AddIdentity<ApplicationUser, IdentityRole>(options =>
            {
                options.Password.RequireLowercase = true;
            })
            .AddEntityFrameworkStores<MyDbContext>()
            .AddUserStore<ApplicationUserStore>()
            .AddDefaultTokenProviders();

            services.Configure<IdentityOptions>(options =>
            {
                options.ClaimsIdentity.UserNameClaimType = Claims.Name;
                options.ClaimsIdentity.UserIdClaimType = Claims.Subject;
                options.ClaimsIdentity.RoleClaimType = Claims.Role;
            });

            services.AddOpenIddict()
                .AddCore(options =>
                {
                    options.UseEntityFrameworkCore()
                    .UseDbContext<MyDbContext>();
                })
                .AddServer(options =>
                {
                    options.SetAuthorizationEndpointUris("/connect/authorize")
                     .SetLogoutEndpointUris("/connect/logout")
                     .SetTokenEndpointUris("/connect/token");

                    options.AllowAuthorizationCodeFlow()
                    .AllowRefreshTokenFlow();

                   scopes.
                    options.RegisterScopes(Scopes.Email, Scopes.OpenId, Scopes.OfflineAccess);

                    // Register the signing and encryption credentials.
                    options.AddDevelopmentEncryptionCertificate()
                           .AddDevelopmentSigningCertificate();

                    options.UseAspNetCore()
                    .EnableTokenEndpointPassthrough();
                })
            .AddValidation(options =>
            {
                // Import the configuration from the local OpenIddict server instance.
                options.UseLocalServer();

                // Register the ASP.NET Core host.
                options.UseAspNetCore();
            });

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
            });




        }

任何帮助都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-12 00:14:53

您所看到的行为实际上是“正常的”:当您设置DefaultAuthenticateScheme时,身份验证中间件(也称为app.UseAuthentication()) --通常在ASP.NET核心管道中很早就添加--会自动调用相应的身份验证处理程序来填充HttpContext.User

无论您的MVC操作是用[Authorize]修饰还是用[AllowAnonymous]修饰,这种机制的发生总是独立的。如果OpenIddict无法在Authorization头中找到访问令牌,它会记录一个错误,并告诉身份验证堆栈它无法提供它请求的AuthenticateResult

如果您的MVC操作是用[Authorize]修饰的,身份验证堆栈将要求OpenIddict返回401挑战(除非使用[AllowAnonymous] )。

这就是说,虽然它不能阻止正常工作,但我同意这可能是一个重要的噪音来源,所以我会考虑删除这条日志消息。我打开https://github.com/openiddict/openiddict-core/issues/941来追踪它。

干杯。

票数 1
EN

Stack Overflow用户

发布于 2020-11-27 17:01:58

在我的例子中,我想使用[AllowAnonymous]属性消除DB上下文创建。但不是这样的。因此,我不得不为AuthenticationMiddleware创建自己的替代品,并为异常添加必要的路径。

现在一步一步地。

First.创建中间件:

代码语言:javascript
复制
public class CustomAuthenticationMiddleware
{
    private readonly RequestDelegate _nextWithoutAuth;
    private readonly AuthenticationMiddleware _nextWithAuth;

    private List<PathString> _withoutAuth = new List<PathString>
    {
        "/url/1", "/url/2"
    };

    public CustomAuthenticationMiddleware(RequestDelegate next, 
        IServiceProvider sp)
    {
        _nextWithoutAuth = next;
        _nextWithAuth = ActivatorUtilities
            .CreateInstance<AuthenticationMiddleware>(sp, next);
    }

    public async Task Invoke(HttpContext context)
    {
        var path = context.Request.Path.HasValue ? 
            context.Request.Path.Value : null;

        var withoutAuth = context.Request.Path.HasValue
            && _withoutAuth.Any(it => path.StartsWith(it, StringComparison.OrdinalIgnoreCase));

        if (withoutAuth)
        {
            await _nextWithoutAuth.Invoke(context);
        }
        else
        {
            await _nextWithAuth.Invoke(context);
        }
    }
}

第二.用所需的值填充数组_withoutAuth

第三.在Startup.cs中,用app.UseMiddleware<CustomAuthenticationMiddleware>();代替app.UseAuthentication();

附注:我使用.net核心2.1

p.s.s.如果使用[AllowAnonymous]属性获取所有控制器及其方法并将它们添加到_withoutAuth数组中,则可以改进我的解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61740467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档