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);
}
}