Spring security 重定向到状态码为 999 的页面 [英] Spring security redirects to page with status code 999

查看:200
本文介绍了Spring security 重定向到状态码为 999 的页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

登录成功后spring重定向到/error页面,内容如下

After successful login spring redirects to /error page with the following content

{
  "timestamp" : 1586002411175,
  "status" : 999,
  "error" : "None",
  "message" : "No message available"
}

我正在使用 spring-boot 2.2.4

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
spring.mvc.servlet.load-on-startup=1
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

<小时>

@Configuration
public class DispatcherContextConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }
}

<小时>

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) {
        web.ignoring().antMatchers("/favicon.ico", "/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/**").permitAll()
                .antMatchers("/registration/**").anonymous()
                .anyRequest().authenticated()
                .and()
                    .headers()
                        .defaultsDisabled()
                        .cacheControl()
                    .and()
                .and()
                    .exceptionHandling()
                        .accessDeniedPage("/errors/403")
                .and()
                    .formLogin()
                    .loginPage("/login")
                    .loginProcessingUrl("/login")
                    .failureUrl("/login?error")
                    .defaultSuccessUrl("/log") // I don't want to use force redirect here
                    .permitAll()
                .and()
                    .logout()
                    .logoutUrl("/logout")
                    .deleteCookies("JSESSIONID")
                    .invalidateHttpSession(true)
                    .logoutSuccessUrl("/login?logout")
                    .permitAll()
                .and()
                    .rememberMe()
                    .rememberMeParameter("remember-me")
                    .key("myKey");

    }

    // ...
}

注意:

事实证明该错误是由对我的静态资源之一的请求失败引起的.登录页面包含项目中缺少的 <script src="/resources/my-js-file.js"></script>.我可以通过删除丢失的资源导入来解决这个问题,但这个问题将来可能会再次出现,所以它不是一个修复.

Note:

Turns out that error is caused by failed request to one of my static resources. Login page has <script src="/resources/my-js-file.js"></script> that is missing in the project. I can fix this by removing missing resource import, but the problem can reappear in future so it's not a fix.

我知道我可以使用 .defaultSuccessUrl("/log", true) 强制重定向到起始页面,但我不想要这个.我也希望重定向能够正常工作,尽管没有找到任何资源.

I know I can force redirect to starting page with .defaultSuccessUrl("/log", true) but I don't want this. Also I want redirect to work properly despite of any not found resources.

推荐答案

在浪费了很多时间之后我弄清楚发生了什么.

After wasting a lot of time I figured out what's happening.

所以 spring 找不到登录页面上使用的静态资源之一.但是它不会为该资源返回状态 404,而是尝试呈现错误页面并将请求转发到 /error.然后 spring security 拒绝了这个请求,因为用户没有被授权.它将 /error 请求保存到会话(用于成功登录后重定向)并将用户重定向到登录页面.

So spring can't find one of static resources that is used on login page. But instead of returning status 404 for this resource it tries to render error page and forwards request to /error. Then spring security denies this request because user is not authorized. It saves /error request to session (for redirecting after successful login) and redirects user to login page.

当然用户看不到此重定向,因为状态 302 返回在后台完成的请求.但主要问题是 /error 请求保存在会话中.

Of course user can't see this redirect because status 302 returns for request that is done in background. But the main issue is /error request saved in session.

然后用户登录成功,spring 检查会话是否有此属性,并重定向到 /error 页面.默认情况下 spring 假设您在静态资源中的某处有这样的页面.如果你没有这个页面,你会看到这个带有状态代码 999 的奇怪错误.

Then user logins successfully and spring checks session for this attribute and makes redirect to /error page. By default spring assumes that you have such page somewhere in static resources. If you doesn't have this page you will see this weird error with status code 999.

忽略安全配置中的 /error 页面:

Ignore /error page in security config:

web.ignoring().antMatchers("/favicon.ico", "/resources/**", "/error");

所以这个请求在登录成功后不会被保存到会话中用于用户重定向.您会看到在登录页面上请求静态资源的状态代码将从 302 更改为 404.

So this request will not be saved to session for user redirection after successful login. You will see that on login page status code of request to static resource will change from 302 to 404.

忽略部分 spring boot autoconfig:

Ignore part of spring boot autoconfig:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

这给出了相同的结果,但从配置中禁用了一些 bean ErrorMvcAutoConfiguration 所以要小心.

This gives same result but disables some beans from config ErrorMvcAutoConfiguration so be careful.

这篇关于Spring security 重定向到状态码为 999 的页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆