RBAC权限管理简单原理
RBAC
-
role-Base Access Control
- 基于角色的访问控制
-
组成
- User
- Role
- Permission
- 操作
- 对象
- user-role映射
- role-permission映射
-
安全原则
- 最小权限原则
- 责任分离原则
- 数据抽象原则
数据库
-
user
- id
- user_name
- password
-
role
- id
- role_name
-
user_role
- u_id
- r_id
-
permission
- id
- permission_name
-
role_permission
- r_id
- p_id
功能
- 认证
- authorization
- 授权
- authentication
aop
- 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HasPermission{
String value();
}
- 1
- 2
- 3
- 4
- 5
- 使用注解
@HasPermission("user:delete")
- 1
- 解析注解
- @before
- @around
@Aspect
@Component
public class PermissionAop{
@Around("@annotation(xxx.xxx.HasPermission)")
// 环绕
public Object around(ProceedingJoinPoint joinPoint){
// 获取session
ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpSession session = sra.getRequest().getSession();
// 获取session中的权限
List<String> permissions = (List<String>) session.getAttribute("permission");
// 获取注解内的值
HasPermission annotation = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(HasPermission.class);
String value = annotation.value();
boolean contains = permissions.contains(value);
if(!contains){
throw new Exception("没有该权限");
}
Object object = null;
object = joinPoint.process(joinPoint.getArgs());
return object;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
封装
- UserNameAndPasswordToken
public class UserNameAndPasswordToken{
private String username;
private String password;
// get set
}
- 1
- 2
- 3
- 4
- 5
- 6
- Realm
// 认证和授权的核心
private interface Realm{
// 认证,查询用户信息
UserNameAndPasswordToken authentication(String username);
// 授权,查询权限信息
PermsisionInfo authorization(String username);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- PermissionInfo
// 用于存储权限信息
public class PermissionInfo{
private List<String> roles;
private List<String> permissions;
// get set
}
- 1
- 2
- 3
- 4
- 5
- 6
- Subject
@Component
public class Subject{
@Resource
private Realm realm;
private static Realm myRealm;
// 所有session都存入ONLINE_SESSION
private static Map<String,HttpSession> ONLINE_SESSION = new HashMap<String,HttpSession>();
@PostConstruct
public void init(){
myRealm = realm;
}
public static volid login(String name,String pwd){
UserNameAndPasswordToken token = myRealm.authentication(name);
String username = token.getUsername();
boolean usernameIsExist = ONLINE_SESSION.containsKey(username);
if(usernameIsExist){
// 踢出重名
ONLINE_SESSION.get(username).invalidite();
}
if(!token.getPassword().equals(pwd)){
throw new Exception("密码错误");
}
getSession().setAttribute("user",username);
getSession().setAttribute("roles",myRealm.authorization(username).getRoles());
getSession().setAttribute("permissions",myRealm.authorization(username).getPermissions());
ONLINE_SESSION.put(username,getSession());
}
public static HttpSession getSession(){
// 获取session
ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpSession session = sra.getRequest().getSession();
return session;
}
public static Map<String,HttpSession> getOnline(){
return ONLINE_SESSION;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
使用封装
// 实现接口Realm
@Component
public class UserRealm implements Realm{
@Autowrited
private UserService userService;
@Autowrited
private RoleService roleService;
@Autowrited
private PermissionService permissionService;
// 认证,查询用户信息
public UserNameAndPasswordToken authentication(String username){
if(StringUtils.isEmpty(username)){
throw new Exception("用户名为空");
}
// 使用userService查询用户
List<Usaer> userByName = userService.findUserByName(username);
if(userByName==null || userByName.size()==0){
throw new Exception("用户没有找到");
}
return new UserNameAndPasswordToken(userByName.get(0).getUsername(),userByName.get(0).getPassword());
}
// 授权,查询权限信息
public PermsisionInfo authorization(String username){
List<String> permissions = permissionService.getPermissionsByUserName(username);
List<String> roles = roleService.getRolesByUserName(username);
PermissionInfo permissionInfo = new PermissionInfo();
permissionInfo.setPermissios(permissions);
permissionInfo.setRoles(roles);
return permissionInfo;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 登录时调用
Subject.login(username,password);
- 1
过滤器
// 需要将过滤器加入springboot配置
public class LoginFilter implements Filter{
public String[] ignoreUrl;
public void init(FilterConfig filterConfig) throws ServletException{
String ignore = filterConfig.getInitParameter("ignore");
ignoreUrl = ignore.splot(",");
}
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain){
boolean isIgnore = isIgnore(servletRequest);
HttpServletRequest request = (HttpServletRequest)servletRequest;
HttpServletResponse response = (HttpServletResponse)servletResponse;
if(isIgnore){
filterChain.doFilter(servletRequest,servletResponse);
}else{
HttpSession session = request.getSession();
Object user = session.getAttribute("user");
if(user==null){
// 未登录
// 重定向
response.sendRedirect("/");
}else{
filterChain.doFilter(servletRequest,servletResponse);
}
}
}
public boolean isIgnore(HttpServletRequest request){
for(String ignore: ignoreUrl){
if(request.getRequestURU().equals(ignore)){
return true;
}
}
return false;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
推荐阅读