开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看详情
spring security优缺点
可以完成项目初始化与数据库的使用之后,项目最重要的安全性就需要考虑了,用户登录访问时是否为该项目的用户,是否禁止该用户访问,当用户访问某些数据时是否有权限访问,是否可以进行操作,这就是web应用的认证与授权,这两者在项目中是通用存在的;在spring所有项目中有一个安全框架SpringSecurity,它提供了丰富的功能,并且与spring项目可以无缝整合;
相比于Shiro拥有更加全面的权限控制,springboot整合该框架比较简单,可以使用更加少的配置来使用该框架,所以常用于springboot与spring cloud项目,专门为web项目开发而设计出来的安全框架;缺点是对于shiro来说整合在spring项目(spring,springmvc,mybatis)中整合起来较为麻烦,shiro更加轻便,shiro也可以脱离web环境进行使用,在新版本中springsecurity也支持对该框架的核心模块抽取,可以独立使用;
快速实践
//引入依赖 spring boot版本使用2.2.0以上版本
<dependencies>
<!-- ... other dependency elements ... -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
</dependencies>
当引入依赖后如果访问接口会跳转安全框架的默认登录页,用户名为user,密码会输出到控制台,也就是说当引入依赖后该框架就会生效;该框架的核心思想是通过一系列的过滤器链来实现基于用户角色权限控制(RBAC思想),当项目引入并启动后自动进行配置;
过滤流程:
//整体过滤器链组成部分
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
UsernamePasswordAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
三个核心过滤器:
FilterSecurityInterceptor:方法级权限过滤器,位于最底部;
其中第一个断点位置标识查看之前的过滤是否通过,第二个断点位置标识调用后台服务;
ExceptionTranslationFilter:异常过滤器,处理认证,授权过程中的异常;
UsernamePasswordAuthenticationFilter:对/login方法POST请求进行拦截并校验用户名密码信息;
UserDetailService:
快速实践中的用户名与密码是由框架进行生成,实际应用中我们数据来源于用户注册后保存在数据库中的数据,所以需要我们根据自己需求进行自定义认证逻辑进行控制;这时就需要用到UserDetailService接口:
基于数据库用户登录简单示例
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok 用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
实体类
@Data
public class Users {
private Integer id;
private String username;
private String password;
}
登录实现类
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String s) throws
UsernameNotFoundException {
QueryWrapper<Users> wrapper = new QueryWrapper();
wrapper.eq("username",s);
Users users = usersMapper.selectOne(wrapper);
if(users == null) {
throw new UsernameNotFoundException("用户名不存在!");
}
List<GrantedAuthority> auths =
AuthorityUtils.commaSeparatedStringToAuthorityList("role");
return new User(users.getUsername(),
new BCryptPasswordEncoder().encode(users.getPassword()),auths);
}
}
配置类编写:放行登录页于静态资源等
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 注入 PasswordEncoder 类到 spring 容器中
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// 配置认证
http.formLogin()
.loginPage("/index") // 配置哪个 url 为登录页面
.loginProcessingUrl("/login") // 设置哪个是登录的 url。
.successForwardUrl("/success") // 登录成功之后跳转到哪个 url
.failureForwardUrl("/fail");// 登录失败之后跳转到哪个 url
http.authorizeRequests()
.antMatchers("/layui/**","/index") //表示配置请求路径
.permitAll() // 指定 URL 无需保护。
.anyRequest() // 其他请求
.authenticated(); //需要认证
// 关闭 csrf
http.csrf().disable();
}
控制器类
@PostMapping("/success")
public String success(){
return "success";
}
@PostMapping("/fail")
public String fail(){
return "fail";
}
页面中登录提交方式POST,用户名与密码字段为username,password,因为会走dAuthenticationFilter过滤器;或者通过配置类进行修改;当页面访问进行用户登录调用时就会根据我们代码中配置的认证过滤进行认证;
本文中讲述了一部分认证相关的知识,最后总结一下:springsecurity框架本质为过滤链,其中请求到达服务器先进入认证过滤器,经过身份认证过滤器(可以使用框架提供的或自定义过率器,自定义过滤器需要在配置类中进行配置),UsernamePasswordAuthenticationFilter(身份认证),ExceptionTranslationFilter(异常过滤,捕获异常进行处理),FilterSecurityInterceptor(权限过滤,进行权限校验与放行);
明天继续更新springsecurity授权部分与csrf相关概念!!!晚安,JYM!!!