SpringSecurity
SpringSecurity是一个基于Spring开发的非常强大的权限验证框架,其核心功能包括:
- 认证 (用户登录)
- 授权 (此用户能够做哪些事情)
- 攻击防护 (防止伪造身份攻击)
认证
基于内存验证
直接以代码的形式配置我们网站的用户和密码,配置方式非常简单,只需要在Security配置类中注册一个Bean即可:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean //UserDetailsService就是获取用户信息的服务
public UserDetailsService userDetailsService() {
//每一个UserDetails就代表一个用户信息,其中包含用户的用户名和密码以及角色
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER") //角色目前我们不需要关心,随便写就行,后面会专门讲解
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("ADMIN", "USER")
.build();
return new InMemoryUserDetailsManager(user, admin);
//创建一个基于内存的用户信息管理器作为UserDetailsService
}
}
withDefaultPasswordEncoder()被弃用,现在推荐使用BCryptPasswordEncoder()。
基于数据库校验
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
...
//手动创建一个AuthenticationManager用于处理密码校验
private AuthenticationManager authenticationManager(UserDetailsManager manager,
PasswordEncoder encoder){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(manager);
provider.setPasswordEncoder(encoder);
return new ProviderManager(provider);
}
@Bean
public UserDetailsManager userDetailsService(DataSource dataSource,
PasswordEncoder encoder) throws Exception {
JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);
//为UserDetailsManager设置AuthenticationManager即可开启重置密码的时的校验
manager.setAuthenticationManager(authenticationManager(manager, encoder));
return manager;
}
}
自定义验证
Service内容
@Service
public class AuthorizeService implements UserDetailsService {
@Resource
UserMapper mapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Account account = mapper.findUserByName(username);
if(account == null)
throw new UsernameNotFoundException("用户名或密码错误");
return User
.withUsername(username)
.password(account.getPassword())
.build();
}
}
自定义登录页面
配置config
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
...
//如果你学习过SpringSecurity 5.X版本,可能会发现新版本的配置方式完全不一样
//新版本全部采用lambda形式进行配置,无法再使用之前的and()方法进行连接了
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
//以下是验证请求拦截和放行配置
.authorizeHttpRequests(auth -> {
auth.anyRequest().authenticated(); //将所有请求全部拦截,一律需要验证
})
//以下是表单登录相关配置
.formLogin(conf -> {
conf.loginPage("/login"); //将登录页设置为我们自己的登录页面
conf.loginProcessingUrl("/doLogin"); //登录表单提交的地址,可以自定义
conf.defaultSuccessUrl("/"); //登录成功后跳转的页面
conf.permitAll(); //将登录相关的地址放行,否则未登录的用户连登录界面都进不去
//用户名和密码的表单字段名称,不过默认就是这个,可以不配置,除非有特殊需求
conf.usernameParameter("username");
conf.passwordParameter("password");
})
.build();
}
}
遇到302
看有没有放行
//以下是csrf相关配置
.csrf(conf -> {
conf.disable(); //此方法可以直接关闭全部的csrf校验,一步到位
conf.ignoringRequestMatchers("/xxx/**"); //此方法可以根据情况忽略某些地址的csrf校验
})
.build();