亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

教你Spring Cloud保證各個(gè)微服務(wù)之間調(diào)用安全性

 更新時(shí)間:2021年08月20日 10:08:37   作者:碼農(nóng)架構(gòu)  
在微服務(wù)的架構(gòu)下,系統(tǒng)會(huì)根據(jù)業(yè)務(wù)拆分為多個(gè)服務(wù),各自負(fù)責(zé)單一的職責(zé),在這樣的架構(gòu)下,我們需要確保各api的安全性,今天通過本文給大家分享Spring Cloud中如何保證各個(gè)微服務(wù)之間調(diào)用的安全性,需要的朋友參考下吧

導(dǎo)讀:在微服務(wù)的架構(gòu)下,系統(tǒng)會(huì)根據(jù)業(yè)務(wù)拆分為多個(gè)服務(wù),各自負(fù)責(zé)單一的職責(zé),在這樣的架構(gòu)下,我們需要確保各api的安全性,也就是說服務(wù)不是開放的,而是需要授權(quán)才可訪問的,避免接口被不合法的請(qǐng)求所訪問。

但是在在微服務(wù)集群中服務(wù)之間暴力的接口,或者對(duì)于第三方開放的接口如果不做及安全和認(rèn)證,后果可想而知。

閱讀下文之前思考幾個(gè)問題:

  • 如何在restTemplate遠(yuǎn)程調(diào)用請(qǐng)求增加添加統(tǒng)一認(rèn)證?
  • 服務(wù)認(rèn)證如何規(guī)范加密和解密?
  • 遠(yuǎn)程調(diào)用統(tǒng)一什么協(xié)議比較合適?

如下圖,三個(gè)服務(wù)注冊(cè)到同一個(gè)注冊(cè)中心集群,服務(wù)A、B、C之間如果不做任何限制,服務(wù)之間的接口基本是互通的。

圖片

但是如果A、B、C之間要做服務(wù)認(rèn)證該如何設(shè)計(jì)?如果外部定制集成服務(wù)D接入怎么保證服務(wù)的安全性?

怎么加認(rèn)證?

假設(shè)服務(wù)A是組織架構(gòu)服務(wù),服務(wù)B是規(guī)則引擎服務(wù),服務(wù)C是公式引擎服務(wù),如果B、C請(qǐng)求A服務(wù)調(diào)用用戶信息除了開放接口規(guī)定參數(shù)。我們?nèi)绾渭尤霗?quán)限認(rèn)證信息。

目前市面上主要兩種方案處理

  • 請(qǐng)求體Body中加入?yún)?shù)校驗(yàn) => SDK集成場景較多
  • 請(qǐng)求頭Header中加入認(rèn)證信息 token

請(qǐng)求頭Header中加入認(rèn)證信息 token,如下圖結(jié)構(gòu)所示。

圖片

確定服務(wù)認(rèn)證統(tǒng)一在request header 加X-SERVICE-NAME,在服務(wù)服務(wù)中我們不可能每個(gè)服務(wù)都會(huì)主動(dòng)去管理基礎(chǔ)認(rèn)證信息,仔細(xì)閱讀RestTemplate源碼不難發(fā)現(xiàn),RestTemplate實(shí)現(xiàn)接口InterceptingHttpAccessor,因此我們可以再定義自己的攔截器來統(tǒng)一處理。

圖片

攔截@FeignClient 標(biāo)識(shí)攔截

feign遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理,重新定義 RequestInterceptor

public class FeignApiInterceptor implements RequestInterceptor {
 
    /**
     * 統(tǒng)一處理feign的遠(yuǎn)程調(diào)用攔截
     */
    @Override
    public void apply(RequestTemplate requestTemplate) {
        // 遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理(簡寫代碼如下)
		requestTemplate.header("X-SERVICE-NAME", "...");
    }
}

攔截RestTemplate遠(yuǎn)程調(diào)用請(qǐng)求

RestTemplate 提供高度封裝的接口,可以讓我們非常方便地進(jìn)行 Rest API 調(diào)用。常見的方法如下:

image.jpg

RestTemplate遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理,統(tǒng)一處理處理restTemplate的請(qǐng)求攔截。

/**
 * restTemplate遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理
 */
@Slf4j
public class RestApiHeaderInterceptor implements ClientHttpRequestInterceptor {
 
    /**
     * 處理restTemplate的請(qǐng)求攔截
     */
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            HttpHeaders headers = request.getHeaders();
            
            // 遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理(簡寫代碼如下)
			requestTemplate.header("X-SERVICE-NAME", "...");
            
            ClientHttpResponse response = execution.execute(request, body);
            
            // 加入鏈路深度Deep
            // ....
            return response;
        } finally {
            // do something
        }
    }
}

服務(wù)注冊(cè)客戶端配置

@Configuration
@EnableFeignClients(basePackages = NamingConstant.BASE_PACKAGE)
public class DiscoveryClientConfig {
    
    //......
    
    /**
     * feign請(qǐng)求攔截器
     */
    @Bean
    public RequestInterceptor feignInterceptor() {
        return new FeignApiInterceptor();
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(HttpClient httpClient,
                                     Environment environment) {
        RestTemplate restTemplate = new RestTemplate();
        restTemplateBuilder.configure(restTemplate);
        restTemplate.setRequestFactory(buildFactory(httpClient, environment));
        // 加入自定義攔截器
        restTemplate.getInterceptors().add(new RestApiHeaderInterceptor());
        return restTemplate;
    }
    
}

拓展補(bǔ)充:

在處理RestTemplate的請(qǐng)求攔截的時(shí)候我們也可以追加鏈路追蹤日志,具體對(duì)于鏈路日志的拓展可查閱《微服務(wù)分布式架構(gòu)中,如何實(shí)現(xiàn)日志鏈路跟蹤?》

簡寫代碼

@Slf4j
public class RestApiHeaderInterceptor implements ClientHttpRequestInterceptor {
 
    /**
     * 處理restTemplate的請(qǐng)求攔截
     */
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        long startTime = System.currentTimeMillis();
        try {
            // 遠(yuǎn)程調(diào)用請(qǐng)求增加頭部信息處理
            ClientHttpResponse response = execution.execute(request, body);
            // 獲取傳遞線程變量
            Collection<String> values = response.getHeaders()
                    .get(TraceUtil.TRACE_RPCCOUNT);
            if (!CollectionUtils.isEmpty(values)) {
                int value = Integer.valueOf(values.iterator().next());
                // 鏈路深度追加
                TraceUtil.getRpcCounter().addAndGet(value + 1);
            }
            return response;
        } finally {
            // 是否開啟鏈路追蹤
            if (TraceUtil.isTraceLoggerOn()) {
                // 輸出鏈路日志(接口耗時(shí))
                TraceUtil.log(StringHelper.join("dt:", System.currentTimeMillis() - startTime,
                        ", TRACE-RPC-", request.getMethod(),
                        ", URI:", request.getURI()));
            }
        }
    }
}

怎么接收認(rèn)證信息?

讀過Spring-Web源碼應(yīng)該知道OncePerRequestFilter過濾器基類,旨在保證在任何 servlet 容器上每個(gè)請(qǐng)求分派一次執(zhí)行。 它提供了一個(gè)帶有 HttpServletRequest 和 HttpServletResponse 參數(shù)的doFilterInternal方法,詳細(xì)用法可閱讀源碼。

另一種也出現(xiàn)在它自己的線程中的調(diào)度類型是ERROR 。 如果子類希望靜態(tài)聲明是否應(yīng)該在錯(cuò)誤調(diào)度期間調(diào)用一次,它們可以覆蓋shouldNotFilterErrorDispatch() 。

getAlreadyFilteredAttributeName方法確定如何識(shí)別請(qǐng)求已被過濾。 默認(rèn)實(shí)現(xiàn)基于具體過濾器實(shí)例的配置名稱。

定義基礎(chǔ)過濾器

public abstract class BaseWebFilter extends OncePerRequestFilter {
 
    /**
     * 返回類名,避免filter不被執(zhí)行
     */
    @Override
    protected String getFilterName() {
        return null;
    }
}

過濾器定義虛擬類, 繼承自接口的過濾器。如果聲明為springbean,他自動(dòng)加載到請(qǐng)求過濾鏈(因?yàn)槔^承了GenericFilterBean接口,spring默認(rèn)把繼承此類的過濾器bean加到web過濾鏈)中,通過注解@order定義其優(yōu)先級(jí)如果不申明為springbean,又要加入到過濾鏈中,可以通過FilterRegistrationBean定義,并指定優(yōu)先級(jí)

封裝攔截 ApiValidationFilter

@Override
public BaseWebFilter getFilterInstance() {
    return new BaseWebFilter() {
        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
            // 攔截校驗(yàn)
            if (validateToken(request)) {
                // 校驗(yàn)通過執(zhí)行下一個(gè)lan'j
                chain.doFilter(request, response);
            } else {
                // 封裝統(tǒng)一認(rèn)證失敗返回信息
                response.setStatus(401);
                response.setCharacterEncoding(
                    Charset.defaultCharset().displayName());
                response.setContentType(
                    MimeTypeUtils.APPLICATION_JSON.toString());
                response.getWriter().println(JsonUtil.toJsonString(Response
                                                                   .err("status.401")));
            }
        }
    };
}

針對(duì)與validateToken方法這里就不做展開,對(duì)于加密方式大同小異,根據(jù)自己項(xiàng)目情況來定。

private boolean validateToken(HttpServletRequest request) {
		if (!needValidate(request)) {
			return true;
		}
		String security = resolveToken(request);
		if (security == null) {
			log.info("驗(yàn)證信息缺失,請(qǐng)求地址:{}", request.getRequestURI());
			return false;
		}
		try {
            // 解析security加密規(guī)則
			return true;
		} catch (Exception e) {
			log.info("驗(yàn)證信息無效:{},請(qǐng)求地址:{}", security, request.getRequestURI());
			return false;
		}
	}

總結(jié)

回顧整個(gè)方案設(shè)計(jì)與實(shí)現(xiàn),大致可分為以下幾個(gè)步驟

參數(shù)加入位置:請(qǐng)求頭Header還是請(qǐng)求體Body確定加入范圍:@FeignClient客戶端、構(gòu)建RestTemplate以及集成服務(wù)遠(yuǎn)程接口調(diào)用確定攔截位置:Web線程攔截器,用于統(tǒng)一處理線程變量,該過濾器執(zhí)行順序早于springsecurity的過濾器確定加密/解密方式:加密字符串和解密​​​​​​

到此這篇關(guān)于教你Spring Cloud保證各個(gè)微服務(wù)之間調(diào)用安全性的文章就介紹到這了,更多相關(guān)Spring Cloud微服務(wù)調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • maven項(xiàng)目在實(shí)踐中的構(gòu)建管理之路的方法

    maven項(xiàng)目在實(shí)踐中的構(gòu)建管理之路的方法

    這篇文章主要介紹了maven項(xiàng)目在實(shí)踐中的構(gòu)建管理之路的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-05-05
  • 手把手帶你分析SpringBoot自動(dòng)裝配完成了Ribbon哪些核心操作

    手把手帶你分析SpringBoot自動(dòng)裝配完成了Ribbon哪些核心操作

    這篇文章主要介紹了詳解Spring Boot自動(dòng)裝配Ribbon哪些核心操作的哪些操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Mybatis-plus中的@EnumValue注解使用詳解

    Mybatis-plus中的@EnumValue注解使用詳解

    這篇文章主要介紹了Mybatis-plus中的@EnumValue注解使用詳解,在PO類中,如果我們直接使用枚舉類型去映射數(shù)據(jù)庫的對(duì)應(yīng)字段保存時(shí),往往就會(huì)因?yàn)轭愋筒黄ヅ鋵?dǎo)致映射失敗,Mybatis-plus提供了一種解決辦法,就是使用@EnumValue注解,需要的朋友可以參考下
    2024-02-02
  • Mybatis中單雙引號(hào)引發(fā)的慘案及解決

    Mybatis中單雙引號(hào)引發(fā)的慘案及解決

    這篇文章主要介紹了Mybatis中單雙引號(hào)引發(fā)的慘案及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • SSH框架網(wǎng)上商城項(xiàng)目第25戰(zhàn)之使用java email給用戶發(fā)送郵件

    SSH框架網(wǎng)上商城項(xiàng)目第25戰(zhàn)之使用java email給用戶發(fā)送郵件

    這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第25戰(zhàn)之使用java email給用戶發(fā)送郵件,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 如何在IDEA中快速解決Jar沖突詳解

    如何在IDEA中快速解決Jar沖突詳解

    相信很多同學(xué)在過去做項(xiàng)目都遇到過Jar沖突的問題,在本地環(huán)境沒問題,一旦部署到測(cè)試或生產(chǎn)環(huán)境突然就啟動(dòng)報(bào)錯(cuò),報(bào)類似classNotFound的Exception,本文詳細(xì)整理了如何在IDEA中快速解決Jar沖突,需要的朋友可以參考下
    2021-06-06
  • spring boot啟動(dòng)時(shí)加載外部配置文件的方法

    spring boot啟動(dòng)時(shí)加載外部配置文件的方法

    這篇文章主要給大家介紹了關(guān)于spring boot啟動(dòng)時(shí)加載外部配置文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-02-02
  • java實(shí)現(xiàn)自定義表格渲染和編輯

    java實(shí)現(xiàn)自定義表格渲染和編輯

    這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)自定義表格渲染和編輯,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • Java高并發(fā)編程之CAS實(shí)現(xiàn)無鎖隊(duì)列代碼實(shí)例

    Java高并發(fā)編程之CAS實(shí)現(xiàn)無鎖隊(duì)列代碼實(shí)例

    這篇文章主要介紹了Java高并發(fā)編程之CAS實(shí)現(xiàn)無鎖隊(duì)列代碼實(shí)例,在多線程操作中,我們通常會(huì)添加鎖來保證線程的安全,那么這樣勢(shì)必會(huì)影響程序的性能,那么為了解決這一問題,于是就有了在無鎖操作的情況下依然能夠保證線程的安全,需要的朋友可以參考下
    2023-12-12
  • java為移動(dòng)端寫接口開發(fā)實(shí)例

    java為移動(dòng)端寫接口開發(fā)實(shí)例

    本篇文章主要介紹了java如何為移動(dòng)端寫接口,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論