SpringSecurity
依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
几个重要的接口
一. passwordEncoder
- encode 方法用来对明文密码进行加密,返回加密之后的密文。
- matches 方法是一个密码校对方法,在用户登录的时候,将用户传来的明文密码和数据库中保存的密文密码作为参数,传入到这个方法中去,根据返回的 Boolean 值判断用户密码是否输入正确。
package org.springframework.security.crypto.password;
public interface PasswordEncoder {
String encode(CharSequence var1);
boolean matches(CharSequence var1, String var2);
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}
二. UserDetailService接口
主要就是一个业务接口,主要从前端获取用户名,并返回一个UserDetail类型的User对象。
package org.springframework.security.core.userdetails;
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
三. UserDetaile ,就是包含用户名,密码,权限,角色等等一系列的用户对象。
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
配置
- 首先我们自定义 SecurityConfig 继承自 WebSecurityConfigurerAdapter,重写里边的 configure 方法。
- 首先我们提供了一个 PasswordEncoder 的实例,因为目前的案例还比较简单,因此我暂时先不给密码进行加密,所以返回 NoOpPasswordEncoder 的实例即可。
- configure 方法中,我们通过 inMemoryAuthentication 来开启在内存中定义用户,withUser 中是用户名,password 中则是用户密码,roles 中是用户角色。如果需要配置多个用户,用 and 相连。
例子
@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {
/*注入使用哪种密码加密方式*/
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Autowired
private MyUserDetailService userDetailsService;
/*配置web请求*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**","/css/**","images/**");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin()
/*默认进入表单*/
.loginPage("/login.html")
.loginProcessingUrl("/user/login")
.defaultSuccessUrl("/hello")
.and().authorizeRequests()
/*放行的路径*/
.antMatchers("/","/login","/login.html").permitAll()
/*当前用户有admins权限才能使用此接口,如果多个就是含有全部权限才能使用此接口*/
//.antMatchers("/test/index").hasAuthority("admins")
/*,如果多个就是含有全部权限中的任何一个才能使用此接口*/
.antMatchers("/test/index").hasAnyAuthority("admins,manange")
/*除了上面的都要进行验证*/
.anyRequest().authenticated()
.and().csrf().disable();
}
}
自定义的service类,返回UserDetaile对象
@Service
public class MyUserDetailService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
/*根据用户名查询*/
QueryWrapper<Users> wrapper = new QueryWrapper<>();
wrapper.eq("username",username);
Users user = userMapper.selectOne(wrapper);
if (user == null){
throw new UsernameNotFoundException("用户名不存在");
}
List<GrantedAuthority> role = AuthorityUtils.commaSeparatedStringToAuthorityList("abc");
return new User(user.getUsername(),new BCryptPasswordEncoder().encode(user.getPassword()),role);
}
}
Role的配置,由于源码ROLE_开头,所以,写角色权限的名称一定要记得手动加ROLE_开头
private static String hasAnyRole(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_");
return "hasAnyRole('ROLE_" + anyAuthorities + "')";
}
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
Assert.isTrue(!role.startsWith("ROLE_"), () -> {
return "role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'";
});
return "hasRole('ROLE_" + role + "')";
}
版权声明:本文为weixin_45633353原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。