在Spring 框架系列中,Spring Security是个功能强大且高度可定制的身份验证和访问控制框架。它主要专注于为Java应用程序提供身份验证和授权的框架。
官方文档:中文版地址
注:当前使用的security框架版本为5.6.1版本,属于旧版的security,security框架从6.x开始配置方式就发生了改变,不在继承WebSecurityConfigurerAdapter
抽象类而是使用配置Bean对象的方式进行配置管理,并且书写方式上也开始使用lambda表达式的方式进行配置。
核心功能:
身份验证(Authentication):用于证明你自己是你自己,是用来确认你的身份。
授权(Authorization):用于证明你能做什么,是用来确认你的权限。
maven 坐标依赖:传送门
基础配置:
环境搭建:新建一个WEB项目,新建springmvc的一个初始化类和两个配置类,再配置spring security的初始化类和配置类,通过springmvc的初始化类在目测的root配置类的位置将security的配置类加载进来。
创建Controller包,新建一个测试类,在MVC的配置类中将此包加入扫描目录,同时将MVC的Servlet配置类中添加@EnableWebMvc注解,启用注解控制。
**简单配置后效果:**当为项目配置了Spring Security框架后,再去访问项目中的web接口不会直接返回结果,而是先跳转到spring security默认的登录界面,经过登录验证后才可以访问原本接口资源。
spring security 默认配置:
自定义进阶配置:
**引入配置:**可以通过配置@EnableWebSecurity注解并继承WebSecurityConfigurerAdapter类来实现,其中注解的作用非常关键,引入了两个核心配置类WebSecurityConfiguration,AuthenticationConfiguration。 配置类所继承的类是使用的适配器模式去实现,
优点是:可以选择性的覆盖想要修改的部分配置,对于其他的配置部分则无影响。
**常见配置:**在继承了WebSecurityConfigurerAdapter的配置类中,有几个常用的重写的方法
configure(AuthenticationManagerBuilder auth):
用于进行身份认证相关的配置。
可以设置用户信息的认证方式,有基于内存、数据库、LDAP等。
可以设置密码的编码器
在基于内存的验证时,添加临时用户,此时密码的编码器是必须的
// 设置密码编码器
private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(encoder)
.withUser("user")
.password(encoder.encode("123456"))
.roles("user");
}
在基于本地数据库的验证时应注意,Mybatis的加载应放在MVC的root根配置类中引入,并且返回自定义的用户类时,名称、密码和角色都需要有。
// UserService ,自定义的登录实现类
public class UserService implements UserDetailsService {
@Resource
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String password = userMapper.getUser(username);
if(password==null){
throw new RuntimeException("登录失败,用户名或密码错误!");
}else {
return User.withUsername(username)
.password(password)
.roles("user")
.build();
}
}
}
// SecurityConfig ,Security 的配置类
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 设置密码加密器
private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
@Resource
private UserService userService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService) // 写入自定义的类
.passwordEncoder(encoder);
}
}
configure(HttpSecurity http):
用于配置url的权限控制。
**特点:**以http 作为根开始配置,每一个 and()对应了一个模块的配置(等同于 xml 配置中的结束标签),并且 and() 返回了 HttpSecurity 本身,于是可以连续进行配置。(链式编程调用)
**使用方法:**调用HttpSecurity.authorizeRequests() 方法后,开始配置 URL 的权限控制。authorizeRequests() 作用:配置路径拦截,表明路径访问所对应的权限,角色,认证信息。
**注意事项:**在使用spring security4.0版本以上时,默认会打开CSRF保护,此时发出的所有post,put,delete,patch请求,在不添加csrfToken时,都会被拒绝,并返回403页面,需注意此点。
常见方法:
- antMatchers() 方法,匹配指定url路径
- anyRequest() 方法,匹配剩余的url请求
- permitAll() 方法,所有用户可访问。
- authenticated() 方法,登录用户可访问。
- denyAll() 方法,所有用户不可访问。
- anonymous() 方法,无需登录,即匿名用户可访问。
- rememberMe() 方法,开启记住我功能,通过 remember me 登录的用户可访问。
- fullyAuthenticated() 方法,非 remember me 登录的用户可访问。
- hasIpAddress(String ipaddressExpression) 方法,来自指定 IP 表达式的用户可访问。
- hasRole(String role) 方法, 拥有指定角色的用户可访问。
- hasAnyRole(String… roles) 方法,拥有指定任一角色的用户可访问。
- hasAuthority(String authority) 方法,拥有指定权限(authority)的用户可访问。
- hasAuthority(String… authorities) 方法,拥有指定任一权限(authority)的用户可访问。
使用注解进行配置:
url配置实例:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/static/**").permitAll() // 允许静态请求通过
.anyRequest().hasAnyRole("user")
.and()
.formLogin()
.loginPage("/login") // 设置登录页面
.loginProcessingUrl("/doLogin") // 设置登录请求接口
.defaultSuccessUrl("/index",true) // 设置登录成功后跳转的页面
.failureForwardUrl("/fail") // 设置登录失败后返回的信息
.permitAll()
.and()
.csrf(AbstractHttpConfigurer::disable); // 关闭CSRF防护
}
授权配置:
对于授权来说有两种形式:
按照角色来控制,是在configure(HttpSecurity http)方法中,设置关于角色的匹配规则,至于角色权限的设置,需要在身份认证的方法中自行设置相应的角色规则。角色在方法中的的指定方式: hasRole(String role) 允许单一角色访问 hasAnyRole(String… roles) 允许多个角色访问