基于 JWT 的 API + Piranha CMS 劫持 [授权] 路由



最近为食人鱼项目中的api设置了JWT。我可以点击登录端点(匿名),而不会被食人鱼劫持请求。

当我使用 [Authorize] 属性到达 API 端点(成功身份验证并收到 JWT 后)时,它总是被食人鱼拾取。 它试图将我重定向到 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 身份如何与 JWT 交互。在你的创业中,你的呼唤:

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

这意味着安装程序使用食人鱼设置的默认选项,其中一些选项实际上更适合开发(如密码强度)。您可以提供自己的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;

此致敬意

哈坎

如果您仍然想在 API 端点上使用 Cookie 身份验证,下面的内容可能会起作用,但需要注意一些。 要进行设置,请执行以下操作:

  1. 为每个 Håkan 的帖子提供默认选项,根据需要更新
  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);
                            }
                        };
                    });

最新更新