SpringBoot集成SpringSecurity

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

(1) 直接配置登录

spring:
  security:
    user:
      name: admin
      password: admin

(2) 内存登录

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

public class SecurityConfig extends WebSecurityConfigurerAdapter ...
   

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser(new User("lucy",passwordEncoder().encode("123"),Collections.emptyList()));
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

(3)查询数据库登录

import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

@Service(value = "userDetailsService")
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().lambda().eq(UserDO::getUsername, username));
        if (userDO == null) {
            throw new UsernameNotFoundException("用户" + username + "不存在!");
        }
        return new User(userDO.getUsername(), passwordEncoder.encode(userDO.getPassword()), Collections.emptyList());
    }
}

(4)自定义登录页面

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                //自定义登录页面
                .loginPage("/login.html")
                //必须与form表单中action的路径保持一致,且form表单必须是post请求
                .loginProcessingUrl("/user/login")
                //false:指定如果用户在验证之前没有访问过安全页面,则在成功验证后将重定向到该配置路径。
                //false:如果访问的是受限地址,那么重定向到受限地址
                //true:登录成功后强制重定向到如下路径
                 .defaultSuccessUrl("/test/index2",false)
                //the URL to send users if authentication fails
                .failureUrl("/test/fail")
                .permitAll()
                .and()
                //anon
                .authorizeRequests().antMatchers("/test/hello","/user/login").permitAll()
                //auth
                .anyRequest().authenticated()
                .and()
                //csrf protected
                .csrf().disable();
    }

(5)权限控制

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter ...

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.   【...】
                .and()
                //start auth and authority
                .authorizeRequests()
                //anon
                .antMatchers("/test/hello", "/user/login").permitAll()
                //对应单条权限:“ROLE_admin”
                .antMatchers("/test/security1").hasRole("admin") 
                //对应权限:“ROLE_admin”或者“ROLE_manager”
                .antMatchers("/test/security2").hasAnyRole("admin","manager") 
                //对应单条权限:“admin”,无“ROLE_”前缀
                .antMatchers("/test/security3").hasAuthority("admin")
                //对应权限:“admin”或者“manager”
                .antMatchers("/test/security4").hasAnyAuthority("admin", "manager")
                //auth
                .anyRequest().authenticated()
                .and()
                【...】
     );
    }


import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

@Service(value = "userDetailsService")
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final UserMapper userMapper;
    private final PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().lambda().eq(UserDO::getUsername, username));
        if (userDO == null) {
            throw new UsernameNotFoundException("用户" + username + "不存在!");
        }
        List<GrantedAuthority> roles = AuthorityUtils.commaSeparatedStringToAuthorityList(userDO.getAuthority());
        return new User(userDO.getUsername(), passwordEncoder.encode(userDO.getPassword()), roles);
    }
}

(6)自定义403路径

    @Override
    protected void configure(HttpSecurity http) throws Exception ...
        http.exceptionHandling().accessDeniedPage("/403.html");

(7)退出logout

    @Override
    protected void configure(HttpSecurity http) throws Exception ...
        http.logout().logoutUrl("/logout")
                .logoutSuccessUrl("/logout.html").permitAll();

(8)注解式权限校验

import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter ...

@RestController
@RequestMapping(value = "/test")
@RequiredArgsConstructor
public class HelloController {

    @GetMapping(value = "/security1")
    @Secured("ROLE_admin")
    public String security1() {
        return "hello security1";
    }

    @GetMapping(value = "/security2")
    @PreAuthorize("hasAnyRole('admin','manager')")
    public String security2() {
        return "hello security2";
    }

    @GetMapping(value = "/security3")
    @PreAuthorize("hasAuthority('admin')")
    public String security3() {
        return "hello security3";
    }

    @GetMapping(value = "/security4")
    @PreAuthorize("hasAnyAuthority('admin','manager')")
    public String security4() {
        return "hello security4";
    }

(9) 自定义加密

public class SpringSecurityPasswordEncoder {
    public static final BCryptPasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
}

public class MyPasswordEncoder implements PasswordEncoder {

    @Override
    public String encode(CharSequence rawPassword) {
        return PASSWORD_ENCODER.encode(rawPassword);
    }

    @SneakyThrows
    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        // 私钥解密
        PrivateKey privateKey = RSAUtil.getPrivateKey("私钥");
        String oldSource = RSAUtil.decryptString(privateKey, rawPassword.toString());
        System.out.println("解密后数据:" + oldSource);

        return PASSWORD_ENCODER.matches(oldSource, encodedPassword);
    }
}

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter ...

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new MyPasswordEncoder());
    }

@Service(value = "userDetailsService")
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {

    private final UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDO userDO = userMapper.selectOne(new QueryWrapper<UserDO>().lambda().eq(UserDO::getUsername, username));
        if (userDO == null) {
            throw new UsernameNotFoundException("用户" + username + "不存在!");
        }
        List<GrantedAuthority> roles = AuthorityUtils.commaSeparatedStringToAuthorityList(userDO.getAuthority());
        return new User(userDO.getUsername(), PASSWORD_ENCODER.encode(userDO.getPassword()), roles);
    }
}

上一篇:Spring Boot:全局异常处理


下一篇:springboot 框架搭建(快速入门)