• Spring Cloud微服务安全实战_3-7_API安全之授权


    API安全之授权

    访问控制:

    1,ACL :Access Control Lists,直接给每个用户授权,他能访问什么。开发简单,但是用户多的话,给每个用户授权比较麻烦。

    2,RBAC:Role Based Access Control。给角色授权,给用户赋予角色。授权简单,开发麻烦。

    下边用ACL来实现简单的权限控制,在用户表里加入permission字段标识权限。

    项目代码结构:

    数据库,User表:

    插入两条数据

     User类:

    /**
     * <p>
     *     User
     * </p>
     *
     * @author 李浩洋
     * @since 2019-10-26
     */
    @Data
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        private Long id;
        private String name;
        private String username;
        private String password;
        private String permissions;
    
    
        public boolean hasPermission(String method){
            boolean result = false;
            if(StringUtils.equalsIgnoreCase("get",method)){
                //如果是get请求,判断user的permissions是否有r
                result = StringUtils.contains(permissions,"r");
            }else {
                //是否有w权限
                result = StringUtils.contains(permissions,"w");
            }
            return result;
        }
    
    }

    拦截

      用拦截器进行拦截,因为授权要在审计之后,审计就是拦截器,如果权限控制用过滤器,就会在审计之前执行

    /**
     * 基于ACL访问控制的权限拦截器
     * 在审计之后执行
     */
    @Component
    public class AclInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            System.err.println("+++授权+++" +4);
            boolean result = true;
            //从request拿用户信息
            User user = (User)request.getAttribute("user");
            if(user == null){
                //未认证
                response.setContentType("text/plain");
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                response.getWriter().write("未认证");
                result = false;
            }else {
                //判断用户是否有权限访问
                if(!user.hasPermission(request.getMethod())){
                    //没权限
                    response.setContentType("text/plain");
                    response.setStatus(HttpStatus.FORBIDDEN.value());
                    response.getWriter().write("未授权");
                    result = false;
                }
            }
            return result;
        }
    }

    webconfig配置:

    @Configuration
    public class SecurityConfig implements WebMvcConfigurer {
    
        //审计日志
        @Autowired
        private AuditLogInterceptor auditLogInterceptor;
        //授权
        @Autowired
        private AclInterceptor aclInterceptor;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(auditLogInterceptor);//.addPathPatterns();//先add的先执行,默认所有请求都拦截
            registry.addInterceptor(aclInterceptor);
        }
    }

    正常的访问:

     控制台打印,可以看到,限流、认证、审计、授权几个过滤器拦截器,是预期的执行顺序

    2019-12-08 20:52:33.857 INFO 50060 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
    2019-12-08 20:52:33.857 INFO 50060 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
    2019-12-08 20:52:33.863 INFO 50060 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
    ++++流控++++ 1
    ++++认证++++ 2
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a3f8551] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.jdbc.JDBC4Connection@1914b4d] will not be managed by Spring
    ==> Preparing: SELECT id,password,permissions,name,username FROM user WHERE (username = ?)
    ==> Parameters: lhy(String)
    <== Columns: id, password, permissions, name, username
    <== Row: 1, 123, r, 阳仔, lhy
    <== Total: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@a3f8551]
    +++审计+++3
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@230e191f] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.jdbc.JDBC4Connection@1914b4d] will not be managed by Spring
    ==> Preparing: INSERT INTO audit_log ( path, method, create_time, username ) VALUES ( ?, ?, ?, ? )
    ==> Parameters: /users/1(String), GET(String), 2019-12-08 20:52:34.143(Timestamp), lhy(String)
    +++审计拦截器,insert+++
    <== Updates: 1
    +++授权+++4
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@230e191f]
    Controller getUser,id=1
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@771b52e5] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.jdbc.JDBC4Connection@1914b4d] will not be managed by Spring
    ==> Preparing: SELECT id,password,permissions,name,username FROM user WHERE id=?
    ==> Parameters: 1(Long)
    <== Columns: id, password, permissions, name, username
    <== Row: 1, 123, r, 阳仔, lhy
    <== Total: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@771b52e5]
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@776808b4] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.jdbc.JDBC4Connection@1914b4d] will not be managed by Spring
    ==> Preparing: SELECT id,path,method,create_time,update_time,username,status FROM audit_log WHERE id=?
    ==> Parameters: 144(Long)
    <== Columns: id, path, method, create_time, update_time, username, status
    <== Row: 144, /users/1, GET, 2019-12-08 20:52:34.0, null, lhy, null
    <== Total: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@776808b4]
    Creating a new SqlSession
    SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@359aa106] was not registered for synchronization because synchronization is not active
    JDBC Connection [com.mysql.jdbc.JDBC4Connection@1914b4d] will not be managed by Spring
    ==> Preparing: UPDATE audit_log SET path=?, method=?, create_time=?, update_time=?, username=?, status=? WHERE id=?
    ==> Parameters: /users/1(String), GET(String), 2019-12-08 20:52:34.0(Timestamp), 2019-12-08 20:52:34.302(Timestamp), lhy(String), 200(Integer), 144(Long)
    <== Updates: 1
    Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@359aa106]
    +++审计拦截器,update+++

    未授权的访问:

    审计日志

     代码:https://github.com/lhy1234/springcloud-security/tree/master/nb-user-api

     ++++++++++++++++++分割线++++++++++++++++++

    小结

    用ACL访问控制列表+拦截器实现了一个简单的权限控制

  • 相关阅读:
    用户自定义异常
    触发异常
    第一阶段冲刺终
    第一阶段冲刺七
    第一阶段冲刺六
    第一阶段冲刺五
    第一阶段冲刺四
    Sufficient Statistic (充分统计量)
    DAG-GNN: DAG Structure Learning with Graph Neural Networks
    Masked Gradient-Based Causal Structure Learning
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/12007201.html
Copyright © 2020-2023  润新知