[Springboot]安全框架Spring Security使用

一、介绍

Spring Security是一个基于Spring框架的安全性框架。
它提供了诸如认证、授权、攻击防御等功能,可以保护Web应用程序中的资源。

二、作用

认证(Authentication)

验证用户的身份。

授权(Authorization)

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


三、SpringBoot项目使用

1、maven依赖


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-securityartifactId>
dependency>

引入后项目就能使用了。
未登录用户会自动跳转到Spring Security提供的登录页面。

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

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

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

@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提供了登录页面,但我们更多的是使用自己的登录页面。

@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 接口
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

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 接口
public class MyLoginFailureHandler implements AuthenticationFailureHandler {
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException {
       	//todo 自定义失败操作
        response.sendRedirect("/fail");
   }
}

在SecurityConfig 配置 AuthenticationFailureHandler

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、退出配置

@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获取登录用户信息

@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

你可能感兴趣的:(Spring,JAVA,spring,安全,java,Spring,Security,authentication,authorization,springboot)