pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
加入依赖后启动项目就已经对资源实现保护,用户名默认user,密码在项目启动中默认打印在控制台中.
当然也可以在application.yml中配置
以上作为学习简单了解下,实际这么配怕是要被祭天…
下面将从数据库中提取用户来实现
第一步:WebSecurityConfigurerAdapter
* spirng sercurity config
* @EnableWebSecurity 开启WebSecurity功能
* @EnableGlobalMethodSecurity 开启方法级别的保护,prePostEnabled = true表示开启@preEnabled和@postEnabled的注解使用,这两个注解支持Spring EL表达式.
* eg: @preEnabled("hasAnyRole('ADMIN','USER')")
* 以上写法加在方法上表示访问该资源需要ADMIN或USER权限
*/
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 该类实现了UserDetailsService接口,重写了 UserDetails loadUserByUsername(String username) throws UsernameNotFoundException; 方法.
* 用于从数据库读取用户信息,返回UserDetails
*/
@Autowired
private CustomUserDetailsService customUserDetailsService;
/**
* 配置认证管理器所需要的用户信息
* @param auth
* @throws Exception
*/
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// 第一种方式(肯定不好用): 通过AuthenticationManagerBuilder 在内存中创建了一个用户信息(认证所需)
// auth.inMemoryAuthentication().withUser("myUserName").password("myPassword").roles("USER");
// 第二种方式(不用这种用哪种): 通过AuthenticationManagerBuilder 从数据库中读取用户信息且告知 加密方式
auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}
/**
* 配置资源保护规则和配置自定义的登录、登出页面
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/home","/user/**").permitAll()
.antMatchers("/test/**").hasAnyRole("USER","ADMIN","DBA")
.and()
//开启cookie储存用户信息,并设置有效期,指定cookie中的密钥
.rememberMe().tokenValiditySeconds(12096).key("mykey")
.and()
.formLogin()
.permitAll();
}
/**
* BCryptPasswordEncoder 加密
* @return
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(6);
}
}
第二步:UserDetailsService
@Service
@Slf4j
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
if(user == null){
log.info("user is null...");
}
log.info("invoke success...user is {}",user);
return user;
}
}
第三步:UserDetails
@Getter@Setter@ToString(exclude = "roles")
@Entity(name = "user")
@Table
public class User implements UserDetails,Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String nickname;
private String telephone;
@Temporal(TemporalType.DATE)
private Date birthday;
private String gender;
private String hobby;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "user_role",joinColumns = @JoinColumn(name = "user_id"),inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles = new ArrayList<Role>();
/**
* 与用户信息所绑定的权限
* @return
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
List<Role> roles = this.getRoles();
for (Role role : roles) {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getRoleName());
authorities.add(authority);
}
return authorities;
}
/**
* 以下四个任一一个返回false,该用户无效,用户无法登陆
* 检查用户帐户是否已过期;
* @return
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 检查用户是否已被锁定;
* @return
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 检查用户凭据是否(密码)已过期;
* @return
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 检查用户是否已启用.
* @return
*/
@Override
public boolean isEnabled() {
return true;
}
}
至此,已经配完了,可以运行项目看效果了