[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

相关推荐
AltmanChan8 分钟前
大语言模型安全威胁
人工智能·安全·语言模型
七星静香15 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员16 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU17 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
马船长18 分钟前
红帆OA iorepsavexml.aspx文件上传漏洞
安全
stewie620 分钟前
在IDEA中使用Git
java·git
Elaine20239135 分钟前
06 网络编程基础
java·网络
G丶AEOM37 分钟前
分布式——BASE理论
java·分布式·八股
落落鱼201338 分钟前
tp接口 入口文件 500 错误原因
java·开发语言
想要打 Acm 的小周同学呀39 分钟前
LRU缓存算法
java·算法·缓存