[Springboot]安全框架Spring Security使用

一、介绍

Spring Security是一个基于Spring框架的安全性框架。

它提供了诸如认证、授权、攻击防御等功能,可以保护Web应用程序中的资源。

二、作用

认证(Authentication)

验证用户的身份。

授权(Authorization)

限制用户对应用程序的访问。


三、SpringBoot项目使用

1、maven依赖

xml 复制代码
<!--Spring Security-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

引入后项目就能使用了。

未登录用户会自动跳转到Spring Security提供的登录页面。

  • 默认用户:user;
  • 默认密码:会在控制台打印Using generated security password: xxxxx 。

2、认证配置------实现 UserDetailsService 接口

登录不可能使用Spring Security默认配置 ,我们需要用自己的账户去登录。

如果我们需要进行以下配置。

java 复制代码
@Service
public class MyUserDetailsService implements UserDetailsService {

    public static record MyUser(String username,String password){};
    public MyUser queryUserFromDB(String username){
        //todo 自定义从数据库查询用户数据
        //这里我定死了一个用户
        return new MyUser(username,"123456");
    }
    // 自定义认证逻辑
    @Override
    public UserDetails loadUserByUsername(String username){
        // 1.查询用户
        MyUser user = queryUserFromDB(username);
        // 2.封装为UserDetails对象
        UserDetails userDetails = User
                .withUsername(user.username)
                .password(user.password)
                .authorities("admin")
                .build();
        // 3.返回封装好的UserDetails对象
        return userDetails;
    }

    /**
     * 配置密码解析器
     * 假如数据库密码没加密,使用NoOpPasswordEncoder
     * 假如数据库密码有加密,使用NBCryptPasswordEncoder
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }
}

3、登录页面配置------继承 WebSecurityConfigurerAdapter 类

Spring Security提供了登录页面,但我们更多的是使用自己的登录页面。

java 复制代码
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    //Spring Security配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 自定义表单登录
        http.formLogin()
           .loginPage("/login.html") //自定义登录页面
           .usernameParameter("username")// 表单中的用户名项
           .passwordParameter("password")// 表单中的密码项
           .loginProcessingUrl("/login") // 登录路径,表单向该路径提交,提交后自动执行UserDetailsService的方法
           .successForwardUrl("/index")//登录成功后跳转的路径
           .failureForwardUrl("/fail");//登录失败后跳转的路径
          // 配置需要认证的资源
         http.authorizeRequests()
         	.antMatchers("/login.html").permitAll() //登录页不需要认证
            .anyRequest().authenticated();//其余所有请求都需要认证
        //关闭csrf防护,默认开启了CSRF防护
        http.csrf().disable();
   }
    @Override
    public void configure(WebSecurity web) throws Exception {
        // 静态资源放行
      web.ignoring().antMatchers("/css/**");
      web.ignoring().antMatchers("/js/**");
      web.ignoring().antMatchers("/img/**");
   }
}

4、如果登录成功/失败,需要额外处理。

登录成功------实现AuthenticationSuccessHandler 接口
java 复制代码
public class MyLoginSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest
request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // 拿到登录用户的信息
        UserDetails userDetails = (UserDetails)authentication.getPrincipal();
        //todo 自定义登录成功操作
        // 重定向到主页
        response.sendRedirect("/index");
   }
}

在SecurityConfig 配置 AuthenticationSuccessHandler

java 复制代码
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    //Spring Security配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	//http.successForwardUrl("/index")
    	http.successHandler(new MyLoginSuccessHandler()) //登录成功处理器
    	//定义successHandler后就不用设置successForwardUrl
    }
}
登录失败------实现AuthenticationFailureHandler 接口
java 复制代码
public class MyLoginFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
       	//todo 自定义失败操作
        response.sendRedirect("/fail");
   }
}

在SecurityConfig 配置 AuthenticationFailureHandler

java 复制代码
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    //Spring Security配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    	//http.failureForwardUrl("/fail");
    	http.failureHandler(new MyLoginFailureHandler());
    	//定义failureHandler后就不用设置failureForwardUrl
    }
}

5、退出配置

java 复制代码
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter{
    //Spring Security配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 退出登录配置
		http.logout()
		   .logoutUrl("/logout") // 退出登录路径
		   .logoutSuccessUrl("/login.html") // 退出登录后跳转的路径
		   .clearAuthentication(true) //清除认证状态,默认为true
		   .invalidateHttpSession(true); // 销毁HttpSession对象,默认为true
   }
}

6、Controller获取登录用户信息

java 复制代码
@RestController
public class MyController {
    // 获取当前登录用户名
    @RequestMapping("/users/username")
    public String getUsername(){
        // 1.获取会话对象
        SecurityContext context = SecurityContextHolder.getContext();
        // 2.获取认证对象
        Authentication authentication = context.getAuthentication();
        // 3.获取登录用户信息
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        return userDetails.getUsername();
   }
}

原文 : https://developer.aliyun.com/article/1135702

相关推荐
HanhahnaH几秒前
Spring集合注入Bean
java·spring
未定义.2216 分钟前
电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
java·软件工程·uml
雾月5524 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
极小狐25 分钟前
极狐GitLab 项目功能和权限解读
运维·git·安全·gitlab·极狐gitlab
24k小善1 小时前
Flink TaskManager详解
java·大数据·flink·云计算
想不明白的过度思考者1 小时前
Java从入门到“放弃”(精通)之旅——JavaSE终篇(异常)
java·开发语言
.生产的驴2 小时前
SpringBoot 封装统一API返回格式对象 标准化开发 请求封装 统一格式处理
java·数据库·spring boot·后端·spring·eclipse·maven
国科安芯2 小时前
面向高性能运动控制的MCU:架构创新、算法优化与应用分析
单片机·嵌入式硬件·安全·架构·机器人·汽车·risc-v
猿周LV2 小时前
JMeter 安装及使用 [软件测试工具]
java·测试工具·jmeter·单元测试·压力测试
晨集2 小时前
Uni-App 多端电子合同开源项目介绍
java·spring boot·uni-app·电子合同