- 首先引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
- 用于测试的登陆用户名和密码:
spring:
security:
user:
name: wwj
password: 123
配置密码加密对象
@Bean
public PasswordEncoder getPasswordEncoder(){
return new BCryptPasswordEncoder();
}
配置认证实现类
@Configuration
@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
实现 UserDetailsService 接口:加载来自数据库的角色权限
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//这里的 String s 实际上是表单传递过来的用户名
//根据用户名查询数据表
UserExample userExample = new UserExample();
UserExample.Criteria criteria = userExample.createCriteria();
criteria.andUsernameEqualTo(s);
List<com.wwj.springsecuritydemo.bean.User> userList = userMapper.selectByExample(userExample);
if (userList == null || userList.isEmpty()) {
//没有查询到用户,认证失败
throw new UsernameNotFoundException("该用户不存在!");
}
//取出用户信息
com.wwj.springsecuritydemo.bean.User user = userList.get(0);
String password = new BCryptPasswordEncoder().encode(user.getPassword());
//权限集合
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
return new User(user.getUsername(), password, authorities);
}
}
添加访问路径的权限配置:
@Configuration
@Component
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.and()
.authorizeRequests()
.antMatchers("/","/hello","/user/login")//配置哪些路径可以直接访问
.permitAll()
.anyRequest().authenticated()//拦截所有资源
.and()
.formLogin()
.loginPage("/login.html")//设置登录页面
.loginProcessingUrl("/user/login")//设置登录的请求路径
.defaultSuccessUrl("/user/index")//设置登录成功后的跳转路径
.permitAll()
.and()
.csrf().disable();//禁用 csrf
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
页面的form 表单:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/user/login" method="post">
用户名:<input type="text" name="username"/><br>
密码:<input type="password" name="password"/><br>
<input type="submit" value="登录">
</form>
</body>
</html>
注解的使用
Spring Security 还支持注解的方式配置,下面介绍常用的五个注解:
-
@Secured
-
@PreAuthorize
-
@PostAuthorize
-
@PreFilter
-
@PostFilter
@Secured 注解用于判断用户是否为某个角色,注意这里也要加上 ROLE_ 前缀,使用该注解前需要在启动类上添加一个注解:
@SpringBootApplication
@MapperScan("com.wwj.springsecuritydemo.dao")
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SpringsecuritydemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecuritydemoApplication.class, args);
}
}
@GetMapping("/testSecured")
@Secured({"ROLE_sale","ROLE_manager"})
public String testSecured(){
return "testSecured";
}
用户注销:
//用户注销
http.logout().logoutUrl("/logout").logoutSuccessUrl("/login.html").permitAll();