【问题标题】:JWT Based API + Piranha CMS HiJacks the [Authorize] Routes基于 JWT 的 API + Piranha CMS 劫持 [Authorize] 路由
【发布时间】:2019-06-16 08:30:40
【问题描述】:

最近在 Piranha 项目中为 api 设置 JWT。我可以在没有 Piranha 劫持请求的情况下点击登录端点(匿名)。

当我使用 [Authorize] 属性到达 API 端点(成功验证并接收 JWT 后)时,Piranha 总是会拾取它。它试图将我重定向到 CMS 登录。

由于这是一个 API,重定向到网页是不可接受的行为。无论如何要纠正这种行为?

        var appSettingsSection = config.GetSection("AppSettings");
        services.Configure<AppSettings> (appSettingsSection);
        // configure jwt authentication
        var appSettings = appSettingsSection.Get<AppSettings> ();
        var key = Encoding.UTF8.GetBytes (appSettings.Secret); // todo - UTF8 vs ASCII?!
        services.AddAuthentication (x => {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer (x => {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey (key),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
        services.AddPiranhaApplication ();
        services.AddPiranhaFileStorage ();
        services.AddPiranhaImageSharp ();

            services.AddPiranhaEF (options =>
                options.UseSqlite ("Filename=./piranha.db"));
            services.AddPiranhaIdentityWithSeed<IdentitySQLiteDb> (options =>
                options.UseSqlite ("Filename=./piranha.db"));
        }
        services.AddPiranhaManager ();
        services.AddPiranhaMemCache ();

        services.AddMvc (config => {
                config.ModelBinderProviders.Insert (0,
                    new Piranha.Manager.Binders.AbstractModelBinderProvider ());
            }).SetCompatibilityVersion (CompatibilityVersion.Version_2_1);

--------- 更新 --------- 在@hakan 的帮助下,以下属性起作用:

[ApiController]
[Route ("api/v1/")]
[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class ApiController : ControllerBase {

【问题讨论】:

    标签: asp.net-core piranha-cms


    【解决方案1】:

    这里的问题实际上是 ASP.NET Identity 如何与 JWT 交互。在您的创业公司中,您的召唤:

    services.AddPiranhaIdentityWithSeed<IdentitySQLiteDb> (options =>
        options.UseSqlite ("Filename=./piranha.db"));
    

    这意味着设置使用 Piranha 设置的默认选项,其中一些选项实际上更适合开发(如密码强度)。您可以在方法中提供自己的optionscookie options,如下所示:

    services.AddPiranhaIdentityWithSeed<IdentitySQLiteDb> (options =>
        options.UseSqlite ("Filename=./piranha.db"), identityOptions, cookieOptions);
    

    使用的默认身份选项是:

    // Password settings
    options.Password.RequireDigit = false;
    options.Password.RequiredLength = 6;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequireUppercase = false;
    options.Password.RequireLowercase = false;
    options.Password.RequiredUniqueChars = 1;
    
    // Lockout settings
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
    options.Lockout.MaxFailedAccessAttempts = 10;
    options.Lockout.AllowedForNewUsers = true;
    
    // User settings
    options.User.RequireUniqueEmail = true;
    

    这些是默认的 cookie 选项:

    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(30);
    options.LoginPath = "/manager/login";
    options.AccessDeniedPath = "/manager/login";
    options.SlidingExpiration = true;
    

    最好的问候

    哈坎

    【讨论】:

    • 太好了,谢谢!!忘记 Piranha Auth 已连接到常规 MVC Auth...必须将此属性应用于 API Controller:[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    【解决方案2】:

    如果您仍想将 Cookie Auth 与您的 API 端点一起使用,以下内容可能会起作用,但有一些注意事项。要进行设置,请执行以下操作:

    1. 根据Håkan's post 提供默认选项,根据需要进行更新
    2. cookieOptions.Events.OnRedirectToLogin 添加自定义处理程序。

    注意事项:

    1. 如果响应没有正文,.NET Core 仍将重定向。
    2. 如果您使用的是 COR,则不再自动发送标头,因此您需要弄清楚如何执行此操作。
    3. 我在前端项目中使用 Axios 客户端。 Axios 默认不会发送带有 PUT/DELETE 请求的 cookie,即使 withCredentials 参数设置为 true
    identityOptions => 
                    {
                        // Password settings
                        identityOptions.Password.RequireDigit = false;
                        identityOptions.Password.RequiredLength = 6;
                        identityOptions.Password.RequireNonAlphanumeric = false;
                        identityOptions.Password.RequireUppercase = false;
                        identityOptions.Password.RequireLowercase = false;
                        identityOptions.Password.RequiredUniqueChars = 1;
    
                            // Lockout settings
                            identityOptions.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                            identityOptions.Lockout.MaxFailedAccessAttempts = 10;
                            identityOptions.Lockout.AllowedForNewUsers = true;
    
                            // User settings
                            identityOptions.User.RequireUniqueEmail = true;
    
                        },
                        cookieOptions => 
                        {
                            cookieOptions.Cookie.HttpOnly = true;
                            cookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(30);
                            cookieOptions.LoginPath = "/manager/login";
                            cookieOptions.AccessDeniedPath = "/manager/login";
                            cookieOptions.SlidingExpiration = true;
    
                            var defaultAction = cookieOptions.Events.OnRedirectToLogin;
                            cookieOptions.Events.OnRedirectToLogin = (context) =>
                            {
    
                                if (context.Request.Path.Value.StartsWith("/api"))
                                {
                                    context.Response.StatusCode = 401;
                                    context.Response.BodyWriter.WriteAsync(new ReadOnlyMemory<byte>(Encoding.ASCII.GetBytes("unauthorized.")));
                                    return Task.CompletedTask;
                                }
                                else
                                {
                                    return defaultAction(context);
                                }
                            };
                        });
    

    【讨论】:

      猜你喜欢
      • 2014-04-14
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      相关资源
      最近更新 更多