Spring Cloud security services combat micro _3-6_API audit of security mechanisms

 

 

Audit log

Definition: Who, what time did nothing.

Location: After authentication, authorization before.

   So you know who is accessing, denial of access can also be off the record. If placed before the certification, then you do not know who is accessing; if placed after authorization, no way to record access is denied.

Storage: audit log must be persistent, recorded in the database or file in memory will be lost. (Output to log service company)

How mind: The request came in record time, request time out, the update log.

    If you only remember when a request comes in, then the request is successful or not is not known. If you only remember at the time the request is returned, then a request if you build up and hung up, did not remember, do not know who is hanging out.

Technical Options: Filter  VS interceptor  VS  ControllerAdvice  VS the AOP

       Filter, good resolution is a request to come out of the implementation or execution of the request;  ControllerAdvice- do global exception handler; AOP - do not say

                 To use interceptor, the interceptor is performed after the filter.

 Limiting filter was @Order annotation, performing a first control

 

 Authentication filter, in the second child row location:

Write audit interceptor, is executed after the filter

achieve

 

 

 

 

database

 Entity classes:

/**
 * <p>
 * 审计日志
 * </p>
 *
 * @author 李浩洋
 * @since 2019-10-27
 */
@Data
public class AuditLog implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    /**
     * http方法
     */
    private String method;

    /**
     * 请求路径
     */
    private String path;

    /**
     * http状态码
     */
    private Integer status;

    /**
     * 请求用户名
     */
    private String username;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 修改时间
     */
    private Date updateTime;


}

审计拦截器:

package com.nb.security.interceptor;

import com.nb.security.entity.AuditLog;
import com.nb.security.entity.User;
import com.nb.security.service.IAuditLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * 审计日志拦截器
 * 拦截流程
 * 流控 -- 认证 --审计 -- 授权 -- 业务
 * 审计要在进入接口之前,insert 数据库(实际可能发送到专门的日志服务器),执行完后 update,过滤器不便于判断拦截之前、之后,故用拦截器
 */
@Component
public class AuditLogInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private IAuditLogService auditLogService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        AuditLog log = new AuditLog();
        log.setMethod(request.getMethod());
        log.setPath(request.getRequestURI());
        log.setCreateTime(new Date());

        User user = (User) request.getAttribute("user");
        if (user != null) {
            user.setUsername(user.getUsername());
        }
        auditLogService.save(log);

        //将审计日志的id传给request,以便于请求处理完成后更新审计日志
        request.setAttribute("auditLogId", log.getId());

        return super.preHandle(request, response, handler);
    }


    /**
     * 请求处理成功失败,都更新审计日志
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        //审计日志id
        Long auditLogId = (Long) request.getAttribute("auditLogId");
        AuditLog log = auditLogService.getById(auditLogId);
        log.setStatus(response.getStatus());
        log.setUpdateTime(new Date());
        auditLogService.updateById(log);

        super.afterCompletion(request, response, handler, ex);
    }
}

拦截器配置:

@Configuration
public class SecurityConfig implements WebMvcConfigurer {

    //审计日志
    @Autowired
    private AuditLogInterceptor auditLogInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(auditLogInterceptor);//.addPathPatterns();//先add的先执行,默认所有请求都拦截
    }
}

用Postman来一个正确的请求:

 

数据库新增了一条数据

 

 

 控制台可以看到执行顺序,就是想要的结果。

 

 错误的访问:

 

 数据库insert了两条数据,一个是我的请求 /users/12 ,另一个 /error 是SpringBoot抛出异常后,会跳到一个/error 的路径, 

 

 

 新建一个异常处理器:

 

 再发一个失败的请求:

 

 数据库就不会再有 /error 请求了。

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

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

小结

本篇说了什么是审计,审计在代码中的位置,以及用拦截器来实现审计

 

Guess you like

Origin www.cnblogs.com/lihaoyang/p/12005668.html