重构-改善既有代码的设计,重构的目的是是软件更容易被理解和修改。git
书接上回Spring Security OAuth 微服务内部Token传递的源码解析,本篇主要无token 调用过程当中,代码的不断完善及其重构过程。spring
需求很简单以下图,若是资源服务器的提供的接口,客户端不须要身份验证即不须要携带合法令牌也能访问,而且能够实现远程调用的安全性校验。 api
ignore-urls:
- /actuator/**
- /v2/api-docs
复制代码
/**
* @author lengleng
* <p>
* 服务间接口不鉴权处理逻辑
*/
@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class PigxSecurityInnerAspect {
private final HttpServletRequest request;
@SneakyThrows
@Around("@annotation(inner)")
public Object around(ProceedingJoinPoint point, Inner inner) {
String header = request.getHeader(SecurityConstants.FROM);
if (inner.value() && !StrUtil.equals(SecurityConstants.FROM_IN, header)) {
log.warn("访问接口 {} 没有权限", point.getSignature().getName());
throw new AccessDeniedException("Access is denied");
}
return point.proceed();
}
}
复制代码
public class PigxRequestGlobalFilter implements GlobalFilter, Ordered {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link GatewayFilterChain}.
*
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono<Void>} to indicate when request processing is complete
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 清洗请求头中from 参数
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(httpHeaders -> {httpHeaders.remove(SecurityConstants.FROM);})
.build();
return chain.filter(exchange.mutate()
.request(newRequest.mutate()
.header(HEADER_NAME, basePath)
.build()).build());
}
@Override
public int getOrder() {
return -1000;
}
}
复制代码
ignore-urls:
- /info/*
复制代码
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
}
复制代码
public class PermitAllUrlProperties implements InitializingBean {
private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");
@Autowired
private WebApplicationContext applicationContext;
@Getter
@Setter
private List<String> ignoreUrls = new ArrayList<>();
@Override
public void afterPropertiesSet() {
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
map.keySet().forEach(info -> {
HandlerMethod handlerMethod = map.get(info);
// 获取方法上边的注解 替代path variable 为 *
Inner method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Inner.class);
Optional.ofNullable(method)
.ifPresent(inner -> info.getPatternsCondition().getPatterns()
.forEach(url -> ignoreUrls.add(ReUtil.replaceAll(url, PATTERN, StringPool.ASTERISK))));
});
}
}
复制代码
@Inner(value=false)
复制代码
@Inner
复制代码
欢迎关注咱们得到更多的好玩JavaEE 实践安全