0
点赞
收藏
分享

微信扫一扫

AuthenticationEntryPoint导致登录页面异常

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

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

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

添加依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
@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

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


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

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

补充依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

补充控制器接口

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

创建登录页面 login.html

<html lang="en"><head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Please sign in</title>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
    <link href="https://getbootstrap.com/docs/4.0/examples/signin/signin.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<div class="container">
    <form class="form-signin" method="post" action="/login">
        <h2 class="form-signin-heading">Please sign in</h2>
        <p>
            <label for="username" class="sr-only">Username</label>
            <input type="text" id="username" name="username" class="form-control" placeholder="Username" required="" autofocus="">
        </p>
        <p>
            <label for="password" class="sr-only">Password</label>
            <input type="password" id="password" name="password" class="form-control" placeholder="Password" required="">
        </p>
        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
    </form>
</div>
</body>
</html>

添加配置

    @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

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

修改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();
    }
}

举报

相关推荐

登录跳转页面

简单登录页面

页面退出登录

登录页面讲解

登录页面表单验证

Web登录页面设计

0 条评论