笔者负责的电商项目的技术体系是基于SpringBoot,为了实现一套后端能够承载ToB和ToC的业务,需要完善现有的权限管理体系。
在查看Shiro和Spring Security对比后,笔者认为Spring Security更加适合本项目使用,可以总结为以下2点:
1、基于拦截器的权限校验逻辑,可以针对ToB的业务接口来做相关的权限校验,以笔者的项目为例,ToB的接口请求路径以/openshop/api/开头,可以根据接口请求路径配置全局的ToB的拦截器;
2、Spring Security的权限管理模型更简单直观,对权限、角色和用户做了很好的解耦。
以下介绍本项目的实现步骤
一、在项目中添加Spring相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.8.RELEASE</version>
</dependency>
二、使用模板模式定义权限管理拦截器抽象类
public abstract class AbstractAuthenticationInterceptor extends HandlerInterceptorAdapter implements InitializingBean {
@Resource
private AccessDecisionManager accessDecisionManager;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//检查是否登录
String userId = null;
try {
userId = getUserId();
}catch (Exception e){
JsonUtil.renderJson(response,403,"{}");
return false;
}
if(StringUtils.isEmpty(userId)){
JsonUtil.renderJson(response,403,"{}");
return false;
}
//检查权限
Collection<? extends GrantedAuthority> authorities = getAttributes(userId);
Collection<ConfigAttribute> configAttributes = getAttributes(request);
return accessDecisionManager.decide(authorities,configAttributes);
}
//获取用户id
public abstract String getUserId();
//根据用户id获取用户的角色集合
public abstract Collection<? extends GrantedAuthority> getAttributes(String userId);
//查询请求需要的权限
public abstract Collection<ConfigAttribute> getAttributes(HttpServletRequest request);
}
三、权限管理拦截器实现类 AuthenticationInterceptor
@Component
public class AuthenticationInterceptor extends AbstractAuthenticationInterceptor {
@Resource
private SessionManager sessionManager;
@Resource
private UserPermissionService customUserService;
@Override
public String getUserId() {
return sessionManager.obtainUserId();
}
@Override
public Collection<? extends GrantedAuthority> getAttributes(String s) {
return customUserService.getAuthoritiesById(s);
}
@Override