美文网首页Spring Cloud
五、API安全机制-审计(日志)

五、API安全机制-审计(日志)

作者: 紫荆秋雪_文 | 来源:发表于2020-05-13 00:22 被阅读0次

源码下载

一、API安全机制-审计(日志) API安全机制.png

审计日志应该在认证处理之后,这样我们就知道谁在发送请求,响应也应该被记录,尤其是请求被拒绝的时候

二、使用@Order注解来控制过滤器的执行顺序 过滤器顺气.png

  • 这个顺序是不符合安全机制的,所以要使用@Order来控制过滤器调用顺序
/**
 * 限流过滤器
 */
@Slf4j
@Order(1)
@Component
public class RateLimitFilter extends OncePerRequestFilter {

    /**
     * 限制1秒只能通过1个请求
     */
    private RateLimiter rateLimiter = RateLimiter.create(1);

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        logger.info("1-限流过滤器");
        if (this.rateLimiter.tryAcquire()) {
            filterChain.doFilter(request, response);
        }
        else {
            // 限流
            response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            response.getWriter().write("Too Many Request !!!");
            response.getWriter().flush();
            return;
        }
    }
}
/**
 * 请求认证过滤器
 */
@Slf4j
@Order(2)
@Component
public class AuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private IRavenUserRepository userRepository;

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        logger.info("2-认证过滤器");
        String header = request.getHeader("Authorization");

        if (StringUtils.isNotBlank(header)) {
            String token64 = StringUtils.substringAfter(header, "Basic ");
            String token = new String(Base64Utils.decodeFromString(token64));
            String[] items = StringUtils.splitByWholeSeparatorPreserveAllTokens(token, ":");

            if (items.length != 2) {
                log.info("用户身份认证错误!!!");
                throw new RuntimeException("用户身份认证错误!!!");
            }
            String username = items[0];
            String password = items[1];
            RavenUser user = this.userRepository.findByName(username);
            if (user != null && user.getPassword().equals(password)) {
                request.setAttribute("user", user);
            }
        }
        filterChain.doFilter(request, response);
    }
}
  • 打印结果
com.raven.security.user.web.filter.RateLimitFilter - 1-限流过滤器
c.r.security.user.web.filter.AuthenticationFilter - 2-认证过滤器

三、Filter、Interceptor、ControllerAdvice、AOP执行顺序 执行顺序.png

  • 定义日志拦截器来拦截请求URL和响应
  • RavenAuditLog
/**
 * 审核日志
 */
@Data
@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "t_auditLog")
public class RavenAuditLog {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String method;

    private String path;

    private Integer status;

    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdTime;

    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date modifyTime;
}
  • RavenAuditLogInterceptor日志拦截器
/**
 * 日志拦截器
 */
@Component
public class RavenAuditLogInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private IRavenAuditLogService auditLogService;


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

        RavenAuditLog log = new RavenAuditLog();
        log.setMethod(request.getMethod());
        log.setPath(request.getRequestURI());

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

        // 保存日志
        this.auditLogService.save(log);

        request.setAttribute("auditLogId", log.getId());

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        Long auditLogId = (Long) request.getAttribute("auditLogId");
        RavenAuditLog auditLog = this.auditLogService.selectById(auditLogId);
        auditLog.setStatus(response.getStatus());
        // 保存日志
        this.auditLogService.save(auditLog);
    }
}
  • RavenInterceptorConfig拦截器生效配置类
/**
 * 拦截器配置类
 */
@Configuration
@EnableJpaAuditing
public class RavenInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private RavenAuditLogInterceptor auditLogInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /**
         * registry.addInterceptor(this.auditLogInterceptor).addPathPatterns("/user");
         * 拦截器指定拦截的url
         */
        registry.addInterceptor(this.auditLogInterceptor);
    }
}
  • 数据日志记录 日志记录.png

    在请求url /users/2时,请求错误本应该只返回状态码500,但是确先返回状态码200,然后又跳转到/error返回状态码500,这样为分析错误会有很大难度,期望是请求/users/2时就直接返回状态码500

  • 解决方案,通过统一处理错误处理器来处理

/**
 * 处理全局异常
 */
@RestControllerAdvice
public class ErrorHandler {

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Map<String, Object>handle(Exception e) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("message", e.getMessage());
        map.put("time", new Date().getTime());
        return map;
    }

}

相关文章

  • 五、API安全机制-审计(日志)

    源码下载 一、API安全机制-审计(日志)API安全机制.png 审计日志应该在认证处理之后,这样我们就知道谁在发...

  • API 安全机制 | 审计日志

    审计日志 审计在认证之后,授权之前; 在认证之后,才知道是谁; 在授权之前,才能记录下被授权机制拒绝的请求; 审计...

  • 八、API安全机制-数据库层安全策略

    源码下载 一、API安全机制-数据库层安全策略API安全机制.png 在前面说的API安全机制包含业务逻辑外(流控...

  • 四、API安全机制-认证

    源码下载 一、API安全机制-认证API安全机制.png 认证过滤器

  • 日志审计系统的基本原理

    日志审计系统简介 什么是日志审计? 综合日志审计平台,通过集中采集信息系统中的系统安全事件、用户访问记录、系统运行...

  • 六、API安全机制-访问控制(授权)

    源码下载 一、API安全机制-访问控制 API安全机制.png 访问控制 访问控制算是API业务层的安全策略,为了...

  • 阿里大师带你详解API接口安全

    API安全机制 为什么要保证API安全 接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设...

  • 三、API安全机制-流控

    源码下载 一、API安全机制-流控API安全机制.png controller 流控过滤器 流控效果请求次数太多.png

  • rsyslog日志管理

    一:日志的重要性 日志分类:系统日志,进程日志,应用程序日志记录日志的用处:排错,追溯事件,统计流量,审计安全行为...

  • API安全机制

    为什么要保证API安全 防止别人随便调用你的api 保证传输数据的安全 设计签名 防止别人调用你的API其实并不难...

网友评论

    本文标题:五、API安全机制-审计(日志)

    本文链接:https://www.haomeiwen.com/subject/fklwnhtx.html