[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

相关推荐
儿时可乖了6 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
ruleslol8 分钟前
java基础概念37:正则表达式2-爬虫
java
xmh-sxh-131424 分钟前
jdk各个版本介绍
java
Koi慢热27 分钟前
路由基础(全)
linux·网络·网络协议·安全
天天扭码43 分钟前
五天SpringCloud计划——DAY2之单体架构和微服务架构的选择和转换原则
java·spring cloud·微服务·架构
程序猿进阶44 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
FIN技术铺1 小时前
Spring Boot框架Starter组件整理
java·spring boot·后端
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
陈王卜1 小时前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、1 小时前
Spring Boot 注解
java·spring boot