AuthenticationEntryPoint导致登录页面异常

  在使用Spring Security的时候我们可能会自定义一个AuthenticationEntryPoint类的实现类,配置该类能够对匿名用户进行拦截并返回对应数据。当用户访问被保护资源的时候,在过滤器中被发现是匿名用户则会由这个类进行处理。

  但是添加了这个处理类后默认的登录页面被拦截了,因为是使用匿名用户进行访问导致触发了异常(InsufficientAuthenticationException),然后被交由自定义的AuthenticationEntryPoint实现类进行处理,导致无法进行登录操作。经过测试,发现在配置中开启表单验证可以正常获取认证后的信息。

进行简略的配置 以对该情况进行梳理

添加依赖

        
            org.springframework.boot
            spring-boot-starter-web
        
@RestController
public class DemoController {

    @RequestMapping("/index")
    public String index() {
        return "Spring Security";
    }

}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("user")
                .password("123456")
                .roles("admin");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                // 添加请求失败处理程序
                .exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPointImpl())
                .and()
                // 拦截全部请求
                .authorizeRequests().anyRequest().authenticated();
    }

}
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, org.springframework.security.core.AuthenticationException e) throws IOException, ServletException {
        e.printStackTrace();
    }
}

由于我们没有自定义登录页面,所以默认地址是/login

对登录地址进行请求出现如下情况:


InsufficientAuthenticationException

现在,在配置中开启表单验证 formLogin()(开启后默认地址为 /login),并使用POST请求对接口进行访问,发现并未出现异常。

基于以上情况我们可以自定义一张登录页面来解决这个问题

补充依赖

        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

补充控制器接口

    @RequestMapping("/login")
    public ModelAndView login() {
        return new ModelAndView("login");
    }

创建登录页面 login.html


    
    
    
    
    Please sign in
    
    


添加配置

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                // 开启表单验证 设置登录页面地址 登录成功后跳转到 /index
                .formLogin().loginPage("/login").successForwardUrl("/index")
                .and()
                .authorizeRequests()
                // 放行登录接口
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPointImpl());
    }

完成以上配置后在浏览器中访问 /login

AuthenticationEntryPoint导致登录页面异常_第1张图片

登录后访问自定义的接口 /index

AuthenticationEntryPoint导致登录页面异常_第2张图片

修改AuthenticationEntryPoint实现类以对匿名用户返回对应的json数据

public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {

    @Override
    public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, org.springframework.security.core.AuthenticationException e) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter out = response.getWriter();
        out.write("{message:\"请求失败,请登录!\"}");
        out.flush();
        out.close();
    }
}
AuthenticationEntryPoint导致登录页面异常_第3张图片

你可能感兴趣的:(AuthenticationEntryPoint导致登录页面异常)