为了账号安全,请及时绑定邮箱和手机立即绑定

Spring Security入门(自定义配置)

1 引入依赖

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

2 配置

@Configuration
public class BrowserSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()  // 表单验证
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated(); // 认证拦截所有请求
    }
}

3 自定义用户认证逻辑

  • 1.自定义用户信息获取逻辑

实现UserDetailService接口

public class DefaultUserDetailService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.info("登录用户:{}",username);
        User user = getUser(username);
        return user;
    }

    private User getUser(String username) {
	    // 用户获取逻辑,通常情况下从数据库获取
      
    }
}
  • 2.自定义用户密码认证逻辑
    配置默认的加密算法实现,也可以自己实现PasswordEncoder接口实现自己的加密逻辑,需要注册,此加密逻辑需要和用户注册逻辑保持一致
    @Bean
    @ConditionalOnMissingBean(PasswordEncoder.class)
    public PasswordEncoder passwordEncoder(){
        log.info("load default password encoder by BCrypt");
        return new BCryptPasswordEncoder();
    }
    1. 自定义登录页面
    • 3.1 自定义登录页
      在resources目录下创建static目录,并在static目录下创建default-login.html页面
<!doctype 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="">
    <link rel="icon" href="../../../../favicon.ico">
    <title>登录</title>

    <!-- Bootstrap core CSS -->
    <link href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
    <!-- Custom styles for this template -->
    <link href="css/default-login.css" rel="stylesheet">
</head>

<body class="text-center">
<form class="form-signin" action="/authentication/form" method="post">
    <h1 class="h3 mb-3 font-weight-normal">用户登录</h1>
    <input type="text"  class="form-control" name="username" placeholder="请输入用户名" required autofocus>
    <input type="password"  class="form-control" name="password" placeholder="请输入密码" required>
    <div class="checkbox mb-3">
        <label>
            <input type="checkbox" value="remember-me"> 记住我
        </label>
    </div>
    <button class="btn btn-lg btn-primary btn-block" type="submit">登录</button>
    <p class="mt-5 mb-3 text-muted">&copy; white-fisher</p>
</form>
</body>
</html>

这个是从bootstrap官网copy过来的简单登录页。配置form表单的提交地址为:/authentication/form,并分别配置两个input表单项的name为’username’和’password’。

  • 3.2 添加配置信息
@Configuration
public class BrowserSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()  // 表单验证
                .loginPage("/default-login.html")
                .loginProcessingUrl("/authentication/form") // 配置表单提交请求,此请求会被UsernamePasswordAuthenticationFilter 拦截处理
                .and()
                .authorizeRequests()
                .antMatchers("/default-login.html").permitAll() 
                .anyRequest()
                .authenticated()  // 认证拦截所有请求
                .and()
                .csrf().disable(); // 关闭跨站请求拦截
    }
}
    1. 自定义登录成功配置
      SpringSecurity默认登录成功后回跳转到之前访问的路径(页面),自定义登录成功之后的逻辑需要如下配置
    • 4.1 编写一个类实现AuthenticationSuccessHandler接口
@Slf4j
@Component
public class DefaultAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("登录成功");
        response.setContentType("application/json;charset=UTF-8");
        // 登录成功以JSON格式返回数据信息
        response.getWriter().write(objectMapper.writeValueAsString(authentication));
    }
}
  • 4.2 配置Handler,告知SpringSecurity以自定义的Handler处理登录成功逻辑
@Configuration
public class BrowserSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private SecurityProperties properties;

    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()  // 表单验证
                .loginPage("/authentication/require")
                .loginProcessingUrl("/authentication/form") // 配置表单提交请求,此请求会被UsernamePasswordAuthenticationFilter 拦截处理
                .successHandler(authenticationSuccessHandler)  // 登录成功配置
                .and()
                .authorizeRequests()
                .antMatchers("/authentication/require",properties.getBrowser().getLoginPage()).permitAll() 
                .anyRequest()
                .authenticated()  // 认证拦截所有请求
                .and()
                .csrf().disable(); // 关闭跨站请求拦截
    }
}
    1. 自定义登录失败配置
      登录失败配置流程与登录成功配置一致,继承AuthenticationFailureHandler接口实现自己相应的登录失败逻辑即可
@Slf4j
@Component
public class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        log.info("登录失败");
        response.setContentType("application/json;charset=UTF-8");
        // 登录成功以JSON格式返回数据信息
        response.getWriter().write(objectMapper.writeValueAsString(exception.getMessage()));
    }
}

添加配置

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()  // 表单验证
                .loginPage("/authentication/require")
                .loginProcessingUrl("/authentication/form") // 配置表单提交请求,此请求会被UsernamePasswordAuthenticationFilter 拦截处理
                .successHandler(authenticationSuccessHandler)  // 登录成功配置
                .failureHandler(authenticationFailureHandler)  // 登录失败配置
                .and()
                .authorizeRequests()
                .antMatchers("/authentication/require",properties.getBrowser().getLoginPage()).permitAll() // 放行登录页
                .anyRequest()
                .authenticated()  // 认证拦截所有请求
                .and()
                .csrf().disable(); // 关闭跨站请求拦截
    }
点击查看更多内容
4人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
8549
获赞与收藏
6550

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消