合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
[TOC] ## 网关模块 网关模块在这个项目里面起到一个统一访问入口的作用。 因为在微服务架构中,有不同的服务,服务之间的访问端口不一样,造成了访问的困难。 网关是对外的,其他内部服务外部系统是无法直接访问到的,需要通过网关。 ## Zuul和Spring Gateway 这2个都可以提供一个网关服务,jfun-cloud现在使用都是zuul,后面会升级成Spring Gateway。 ## 网关和服务发现 网关重要功能就是转发服务,提供统一入口。 所以服务都接入我们还需要一个服务都注册中心,这里使用了nacos这个注册中心。 ## 网关配置服务的转发 比如下面都配置USER-CENTER就是一个用户中心都服务,这个注册在nacos上面了,这里没有使用动态注册,简便的配置了一个服务。 访问网关的api-user就会转发到对应的服务上面 ``` zuul: routes: user-center: path: /api-user/** service-id: USER-CENTER strip-prefix: true ``` ## 服务作为资源中心 前面的权限模块我们说了认证中心。 而微服务里面,我们内部的服务(比如用户服务、订单服务)可以当成一种资源。 那么我们是否可以把每一个服务作为一个资源中心呢? ![](https://box.kancloud.cn/32d43327cb6dca4553cf265d70a95364_1624x1200.jpg) 这种场景下网关起到一个统一入口的作用,每一个服务都是一个独立的资源服务。 ## 网关作为资源中心 基于需要通过网关访问内部服务,而内部服务又是资源,那么现在我让网关委以重任,我把“资源中心”做到网关上面,统一管理(比如配置白名单上面的,统一配置)。 ![](https://box.kancloud.cn/adeaa99bb4b66369aca6b67bf5b15f32_1620x1208.jpg) 这种场景下面,用户访问网关的时候,我们需要做鉴权处理。 jfun-cloud是使用这种方法做的网关服务。 ### 网关权限拦截 ~~~ @Configuration @EnableResourceServer public class OAuth2ResourceServerConfig extends OAuth2ClientConfig { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .requestMatchers(CorsUtils::isPreFlightRequest).permitAll() .anyRequest().access("@authenticationService.hasPermissions(request,authentication)"); } } ~~~ ~~~ @Override public boolean hasPermissions(HttpServletRequest authRequest, Authentication authentication) { log.debug("正在访问的url是:{},method:{}", authRequest.getServletPath(), authRequest.getMethod()); AntPathMatcher antPathMatcher = new AntPathMatcher(); final String uri = authRequest.getRequestURI(); //获取数据库里面的资源信息 String tmp = (String) authentication.getName(); Set<Resource> resourceSet = resourceService.findAll(authentication.getName()); //鉴权 Optional<Resource> desc = resourceSet.stream().filter(new Predicate<Resource>() { @Override public boolean test(Resource resource) { return StringUtils.isNotEmpty(resource.getUrl()) && antPathMatcher.match(resource.getUrl(), uri) && StringUtils.isNotEmpty(resource.getMethod()) && authRequest.getMethod().toLowerCase().equals(resource.getMethod().toLowerCase()); } }).peek(resource -> log.info("匹配权限成功:{}", resource.toString())).findFirst(); return desc.isPresent(); } ~~~ ## 更进一步,加上鉴权中心 上面做法网关做了鉴权的操作,这个还可以在进行改造,弄一个鉴权中心,主要就是提供一个服务hasPermissions(判断是否有权限) 这样就可以把网关的鉴权独立出来,不耦合太紧。 ## 见仁见智 上面说了网关和权限在一起做出现的问题。 实际操作中,可以根据业务需求和场景,选择合适的方案