添加依赖,并去 maven 库添加:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
没有这个依赖,html 无法使用 sec 标签
配置连接 mysql 数据库:
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
logging.level.org.springframework.security= INFO
spring.thymeleaf.cache=false
spring.jpa.hibernate.dll-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent-output=true
(这里因为机器安装了 Oracle 占用了 8080 端口,故改为 8081)
logging.level.org.springframework.security= INFO
:security 配置
spring.thymeleaf.cache=false
:关闭 thymeleaf 缓存,否则每重写一行 html 就要重启一遍服务器(缓存的意思是加载一次模板就不加载了)
spring.jpa.hibernate.dll-auto=update
:使表结构随着实体类属性实时更新
spring.jpa.show-sql=true
:在控制台打印真实的 SQL 语句
spring.jackson.serialization.indent-output=true
:格式化JSON语句,阅读美观
对实体类的编写:
角色:
@Entity
@Data
public class SysRole {
@Id
@GeneratedValue
private Long id;
private String name;
}
用户:
@Entity
@Data
public class SysUser implements UserDetails {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
private Long id;
private String username;
private String password;
@ManyToMany(cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
private List<SysRole> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
List<SysRole> roles = this.getRoles();
for (SysRole role : roles) {
auths.add(new SimpleGrantedAuthority(role.getName()));
}
return auths;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
实现 UserDetails 接口,用户实体即为 Spring Security 所使用的用户
(重写 isAccountNonExpired()
、isAccountNonLocked()
、isCredentialsNonExpired()
、isEnabled()
并设置为 true)
@ManyToMany
:表明用户和角色是多对多的关系
CascadeType.REFRESH
:当多个用户同时操作一个实体时,用户获取的数据是实时的
FetchType.EAGER
:急加载,立即从数据库取出数据
当设置用户和角色的多对多关系之后,因为配置了
spring.jpa.hibernate.ddl-auto=update
所以自动生成了用户表:SYS_USER、角色表:SYS_ROLE、关联表:SYS_USER_ROLES
传值对象:
@Data
@AllArgsConstructor
public class Msg {
private String title;
private String content;
private String etraInfo;
}
(测试不同角色用户的数据展示)
数据访问:
public interface SysUserRepository extends JpaRepository<SysUser, Long> {
SysUser findByUsername(String username);
}
根据用户名查出用户
自定义 UserDetailsService:
public class CustomUserService implements UserDetailsService {
@Autowired
SysUserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
SysUser user = userRepository.findByUsername(s);
if(user == null) {
throw new UsernameNotFoundException("用户不存在");
}
return user;
}
}
实现 UserDetailsService 接口
重写 loadUserByUsername 方法获得用户
当前用户实现了 UserDetails 接口,所以可直接返回给 Spring Security 使用
对 Security 的配置:
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
UserDetailsService customUserService() {
return new CustomUserService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").failureUrl("/login?error").permitAll()
.and()
.logout().permitAll();
}
}
继承 WebSecurityConfigurerAdapter
注册 CustomUserService 的 Bean
添加认证
对于所有请求均需要认证 即登陆后才能访问
定制登陆行为,登录页面可任意访问
定制注销行为,注销请求可任意访问