Spring Cloud

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

2020-05-13  本文已影响0人  紫荆秋雪_文

源码下载

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

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

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

/**
 * 限流过滤器
 */
@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

/**
 * 审核日志
 */
@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;
}
/**
 * 日志拦截器
 */
@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);
    }
}
/**
 * 拦截器配置类
 */
@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);
    }
}
/**
 * 处理全局异常
 */
@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;
    }

}
上一篇下一篇

猜你喜欢

热点阅读