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訪問控制列表+攔截器實現了一個簡單的權限控制

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM