999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于Apache Shrio的微服務(wù)認(rèn)證授權(quán)方案

2023-09-14 14:21:46遼河石油勘探局有限公司信息工程分公司林哲
關(guān)鍵詞:用戶服務(wù)信息

遼河石油勘探局有限公司信息工程分公司 林哲

信息化的高速發(fā)展推動(dòng)了計(jì)算機(jī)應(yīng)用架構(gòu)的迭代演進(jìn),傳統(tǒng)單體應(yīng)用項(xiàng)目的認(rèn)證與授權(quán)方式已不適用于基于微服務(wù)架構(gòu)的系統(tǒng)應(yīng)用。本文提出了一種微服務(wù)架構(gòu)下的認(rèn)證授權(quán)方案,基于Apache Shrio整合Oauth2.0協(xié)議,實(shí)現(xiàn)獨(dú)立的微服務(wù)認(rèn)證與授權(quán)中心;整合JWT作為認(rèn)證令牌,增強(qiáng)系統(tǒng)的安全性、易用性。對(duì)于原有項(xiàng)目升級(jí)改造以及微服務(wù)應(yīng)用構(gòu)建開發(fā)均具備一定的參考價(jià)值。

隨著網(wǎng)絡(luò)技術(shù)的發(fā)展、應(yīng)用規(guī)模的不斷擴(kuò)大,以及應(yīng)用場(chǎng)景的日趨復(fù)雜化,計(jì)算機(jī)應(yīng)用架構(gòu)也在不斷演變,逐漸從單體應(yīng)用架構(gòu)演化出了微服務(wù)架構(gòu)等更加有利于資源匹配的架構(gòu)形式。隨之產(chǎn)生的問題是單體架構(gòu)中的認(rèn)證授權(quán)機(jī)制不能直接應(yīng)用到微服務(wù)架構(gòu)中,需要重新設(shè)計(jì)一種認(rèn)證授權(quán)方案,使其符合微服務(wù)無狀態(tài)、資源分散、技術(shù)多樣性等特點(diǎn)。Apache Shrio作為單體應(yīng)用中的主流安全框架,是一個(gè)強(qiáng)大易用的Java安全框架,提供了認(rèn)證、授權(quán)、加密和會(huì)話管理等功能,可以為任何應(yīng)用提供安全保障[1]。Shiro提供的接口使其具有靈活的擴(kuò)展能力,具備擴(kuò)展為微服務(wù)架構(gòu)安全框架的可能性。Oauth2.0協(xié)議的出現(xiàn)則為開發(fā)人員提供了一整套適用于微服務(wù)架構(gòu)的認(rèn)證授權(quán)開發(fā)標(biāo)準(zhǔn)。本文基于上述技術(shù),研究了單體項(xiàng)目和微服務(wù)認(rèn)證授權(quán)的機(jī)制,提出一種微服務(wù)架構(gòu)下的認(rèn)證與授權(quán)方案。

1 技術(shù)路線

1.1 微服務(wù)

微服務(wù)是一種軟件架構(gòu)方案,通常由一組職責(zé)單一、具備自治性的獨(dú)立服務(wù)組成。服務(wù)之間由服務(wù)注冊(cè)、服務(wù)發(fā)現(xiàn)、網(wǎng)關(guān)、鏈路追蹤、熔斷機(jī)制等技術(shù)進(jìn)行管理、維護(hù)。相較于單體項(xiàng)目,微服務(wù)架構(gòu)具備以下優(yōu)勢(shì):

(1)彈性配置。微服務(wù)之間通過一些輕量級(jí)的通信機(jī)制進(jìn)行通信,由于服務(wù)本身及網(wǎng)絡(luò)情況的不確定性,通信間的交互可能出現(xiàn)故障。由于微服務(wù)架構(gòu)中的服務(wù)通常具備獨(dú)立職責(zé)且結(jié)構(gòu)完整,而微服務(wù)應(yīng)用程序的彈性也主要取決于微服務(wù)通信的可靠性。因此微服務(wù)提供了許多機(jī)制來保證微服務(wù)應(yīng)用程序的彈性,其中包括超時(shí)、重試、斷路器、快速故障、隔板、事務(wù)、負(fù)載平衡,故障轉(zhuǎn)移和保證的交付等。(2)獨(dú)立擴(kuò)展。在傳統(tǒng)單體項(xiàng)目中,對(duì)單一服務(wù)進(jìn)行拓展時(shí),由于系統(tǒng)間的服務(wù)耦合度高,導(dǎo)致系統(tǒng)整體也會(huì)受到影響。而微服務(wù)體系是由一組相對(duì)獨(dú)立的服務(wù)組成,可以指向性地針對(duì)特定服務(wù)進(jìn)行單獨(dú)擴(kuò)展,這樣就能根據(jù)實(shí)際需求合理分配資源到不同的服務(wù)中去,從而達(dá)到最佳的性能效果。(3)簡(jiǎn)化部署。單體項(xiàng)目改版發(fā)布的難度隨其代碼規(guī)模的增長(zhǎng)而增長(zhǎng),任何變動(dòng)都需要整個(gè)項(xiàng)目重新部署。對(duì)于大體量項(xiàng)目來說,項(xiàng)目的重新部署以及處理可能產(chǎn)生的BUG都需要很高的成本,且具有很高的風(fēng)險(xiǎn)度。微服務(wù)由于互相之間相對(duì)獨(dú)立,單一微服務(wù)體量小易部署,即使產(chǎn)生BUG,也能夠快速回滾到之前的穩(wěn)定版本進(jìn)行部署,對(duì)當(dāng)前運(yùn)行的其他程序影響不大。

1.2 Apache Shiro

Apache Shiro是一種功能強(qiáng)大且易于使用的Java安全框架,它具有身份驗(yàn)證、訪問授權(quán)、數(shù)據(jù)加密、會(huì)話管理等功能,可用于保護(hù)任何應(yīng)用程序的安全[2]。Shiro主要由3個(gè)組件構(gòu)成,分別為主體(Subject)、安全管理器(Security Manager)和領(lǐng)域(Realm)。

(1)主體。Subject是一個(gè)抽象概念,表示與程序交互的對(duì)象,是Shiro框架對(duì)外的核心對(duì)象。代表當(dāng)前“用戶”,“用戶”一次不一定指的是人,也可以是其他應(yīng)用程序、接口等。Subject作為對(duì)外接口,其中的交互操作實(shí)際都是由Security Manager來完成。(2)安全管理器。Security Manager是Shiro框架的核心組件。所有涉及系統(tǒng)安全的相關(guān)操作都會(huì)與Security Manager進(jìn)行交互,Security Manager負(fù)責(zé)管理Shiro中的其他組件,協(xié)調(diào)各組件共同完成安全管理任務(wù)。(3)領(lǐng)域。Realm是安全信息數(shù)據(jù)源,內(nèi)部封裝了通用數(shù)據(jù)源鏈接,用于作為安全驗(yàn)證的參考數(shù)據(jù)。當(dāng)進(jìn)行授權(quán)、令牌獲取、令牌認(rèn)證等操作時(shí),Shiro通過配置的Realm查找相關(guān)的數(shù)據(jù)信息,Realm可以配置一個(gè)或多個(gè)。當(dāng)Shrio默認(rèn)提供的Realm無法滿足需求時(shí),可以自定義領(lǐng)域?qū)崿F(xiàn),形成定制化數(shù)據(jù)源。

1.3 JWT

Json Web Token (JWT)是一個(gè)基于 RFC7519 的信息傳遞協(xié)議,是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)[3]。JWT是由點(diǎn)符號(hào)連接的3個(gè)部分組成,分別為標(biāo)頭(Header)、載荷(Payload)和簽名(Signature),其中Header存儲(chǔ)了所使用的加密算法和Token類型;Payload是一個(gè)JSON對(duì)象,作為JWT的主體部分,官方規(guī)定了7個(gè)字段供開發(fā)者選用,也可以自定義字段和內(nèi)容;Signature是對(duì)前2個(gè)部分的簽名,作用是防止數(shù)據(jù)篡改。這3個(gè)部分分別單獨(dú)進(jìn)行Base64編碼后使用點(diǎn)符號(hào)拼接成完整的JWT。相比傳統(tǒng)的Session認(rèn)證方式,基于Token的認(rèn)證方式更適用于移動(dòng)端和分布式,且更節(jié)約計(jì)算資源,具備支持跨域訪問、無狀態(tài)、適用于CDN、無需考慮CSRF等特性。

1.4 Oauth2.0

OAuth2.0是一個(gè)授權(quán)第三方服務(wù)訪問Web項(xiàng)目的安全協(xié)議。OAuth2.0將第三方應(yīng)用與用戶的安全信息進(jìn)行分隔,并且提供簡(jiǎn)單、標(biāo)準(zhǔn)的實(shí)現(xiàn)方案來訪問應(yīng)用中受保護(hù)的資源。該協(xié)議具備開放、靈活、簡(jiǎn)單、安全等特點(diǎn)。OAuth2.0采用無狀態(tài)的認(rèn)證授權(quán)方式,以令牌作為安全信息的載體,適用于多服務(wù)獨(dú)立部署的微服務(wù)架構(gòu)。令牌基于Rest風(fēng)格的API在服務(wù)間進(jìn)行傳遞。

1.5 Apache Oltu

Apache Oltu是OAuth2.0協(xié)議基于Java語言的實(shí)現(xiàn),具有輕量、簡(jiǎn)單、靈活等特點(diǎn)。Apache Oltu源碼包分為4個(gè)部分:

(1)Issuer:生成授權(quán)碼和訪問令牌,刷新令牌;(2)Request:封裝授權(quán)碼請(qǐng)求和令牌請(qǐng)求的邏輯,并提供相應(yīng)的校驗(yàn)服務(wù);(3)Response:封裝授權(quán)流程中的響應(yīng)邏輯,提供生成不同響應(yīng)結(jié)果的方法;(4)Validator:為Request提供校驗(yàn)服務(wù)。

2 方案設(shè)計(jì)

(1)微服務(wù)入口處理。微服務(wù)架構(gòu)通常由API網(wǎng)關(guān)作為系統(tǒng)對(duì)外的唯一入口。因此網(wǎng)關(guān)可以整合令牌的初步認(rèn)證。通過獲取請(qǐng)求中的令牌信息,并對(duì)信息進(jìn)行解析、校驗(yàn)等操作,實(shí)現(xiàn)身份認(rèn)證以及部分授權(quán)功能。另外,網(wǎng)關(guān)需要設(shè)置白名單,即驗(yàn)證碼、令牌獲取等請(qǐng)求不需要進(jìn)行身份認(rèn)證即可訪問。(2)獲取授權(quán)碼。當(dāng)外部應(yīng)用對(duì)服務(wù)發(fā)起授權(quán)碼請(qǐng)求時(shí),網(wǎng)關(guān)通過判斷請(qǐng)求在白名單列表中,直接將請(qǐng)求轉(zhuǎn)發(fā)至認(rèn)證中心。認(rèn)證中心對(duì)用戶名密碼進(jìn)行驗(yàn)證,驗(yàn)證通過后生成授權(quán)碼,并以重定向URL參數(shù)的形式返回給用戶。(3)令牌的選擇及獲取。方案采取無狀態(tài)認(rèn)證授權(quán)方式,使用Token作為安全信息載體。為提高令牌的安全性、易用性、靈活性,采用JWT作為令牌實(shí)現(xiàn)。經(jīng)由網(wǎng)關(guān)白名單釋放的令牌獲取請(qǐng)求到達(dá)認(rèn)證中心。認(rèn)證中心對(duì)請(qǐng)求中攜帶的授權(quán)碼驗(yàn)證,驗(yàn)證通過后生成驗(yàn)證碼。(4)資源授權(quán)。當(dāng)請(qǐng)求攜帶有效Token訪問服務(wù)時(shí),網(wǎng)關(guān)通過對(duì)Token的解析,獲取身份信息及權(quán)限信息。并將信息重新加密后通過請(qǐng)求傳遞給資源中心,資源中心解密信息后,將信息存入安全上下文。資源中心根據(jù)上下文中的權(quán)限信息對(duì)請(qǐng)求進(jìn)行授權(quán)并獲取資源,最終完成請(qǐng)求訪問流程。

3 功能實(shí)現(xiàn)

3.1 網(wǎng)關(guān)整合令牌認(rèn)證

通過實(shí)現(xiàn)Spring Cloud Gateway的GlobalFilter實(shí)現(xiàn)對(duì)網(wǎng)關(guān)訪問請(qǐng)求的攔截,從中獲取令牌,并使用JWTStore進(jìn)行解析,獲取權(quán)限信息及身份信息并進(jìn)行身份認(rèn)證。認(rèn)證通過后,將安全信息編碼后添加到請(qǐng)求,通過Filter Chain向后傳遞。

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

String requestUrl = exchange.getRequest().getPath().value();

AntPathMatcher pathMatcher = new AntPath Matcher();

//1 認(rèn)證中心服務(wù)所有放行

if (pathMatcher.match("/sso-server/**",requestUrl)) {

return chain.filter(exchange);

}

//2 檢查token是否存在

String token = getToken(exchange);

if (!StringUtils.hasLength(token)) {

return noTokenMono(exchange);

}

//3 判斷是否是有效的token

OAuth2AccessToken oAuth2AccessToken;

try {

oAuth2AccessToken = tokenStore.readAccess Token(token);

Map<String, Object> additionalInformation =oAuth2AccessToken.getAdditionalInformation();

//取出用戶身份信息

String principal = (String)additionalInformation.get("user_name");

//獲取用戶權(quán)限

List<String> authorities = (List<String>)additionalInformation.get("authorities");

HashMap hashMap = new HashMap();

hashMap.put("principal",principal);

hashMap.put("authorities",authorities);

//給header添加值

String base64 = "";

try {

base64 = EncryptUtil.encodeUTF8StringBase64(new ObjectMapper().writeValueAsString(hashMap));

} catch (IOException e) {

e.printStackTrace();

}

ServerHttpRequest tokenRequest = exchange.get Request().mutate().header("json-token", base64).build();

ServerWebExchange build = exchange.mutate().request(tokenRequest).build();

return chain.filter(build);

} catch (InvalidTokenException e) {

return invalidTokenMono(exchange);

}

}

3.2 獲取授權(quán)碼

授權(quán)碼獲取采用Shiro整合Oltu實(shí)現(xiàn)。通過Subject狀態(tài)判斷用戶是否已登錄,如果通過狀態(tài)判定,則生成授權(quán)碼,并以重定向方式將授權(quán)碼返回給客戶端。

//封裝OAth請(qǐng)求

OAuthAuthzRequest authzRequest=new OAuth AuthzRequest(request);

//檢查client_id

if(!checkClientId(authzRequest.getClientId())){

//錯(cuò)誤則構(gòu)造錯(cuò)誤響應(yīng)

return "error";

}

//判斷用戶登錄狀態(tài)

Subject subject=SecurityUtils.getSubject();

if(!subject.isAuthenticated())

return "oauth2login";

}

//判斷狀態(tài)為登錄成功,則生成授權(quán)碼code

String username=(String)subject.getPrincipal();

String authorizCode=null;

String responseType= authzRequest

.getParam("response_type");

if(responseType.equals("code")){

//生成authCode

OAuthIssuerImpl issuerImpl=new OAuthIssuerImpl(

new MD5Generator());

authorizCode= issuerImpl.authorizationCode();

addAuthCode(authorizCode,username);

}

//重定向回客戶端地址

String redURI=authzRequest

.getParam("redirectUrl");

final OAuthResponse response= OAuthASResponse

.authorizationResponse(request,302)

.setCode(authorizCode)

.location(redURI)

.buildQueryMessage();

HttpHeaders hs=new HttpHeaders();

URI uri = new URI(response.getLocationUri());

hs.setLocation(uri);

return new ResponseEntity(hs, HttpStatus.FOUND);

3.3 獲取令牌

Shiro的領(lǐng)域接口提供了Supports方法,用于設(shè)置Realm支持的Token類型。重寫Supports方法,指定Token驗(yàn)證類型為封裝的JWT類型,為整合JWT做準(zhǔn)備。通過對(duì)自定義Realm中的認(rèn)證方法進(jìn)行重寫,增加令牌認(rèn)證功能。

public class JwtShiroRealm extends AuthorizingRealm{

@Override

public boolean supports(AuthenticationToken token) {

return token instanceof JwtToken;

}

// 認(rèn)證

@Override

protected AuthenticationInfo doGetAuthenticationInfo(Au thenticationToken token) throws AuthenticationException {

String credentials = (String) token.getCredentials();

// 解密獲得username,用于和數(shù)據(jù)庫進(jìn)行對(duì)比

String username = JwtUtil.getUsername(credentials);

if ("admin".equals(username)) {

//數(shù)據(jù)庫查出來的用戶

User user = getUser();

//驗(yàn)證密碼是否正確

if (JwtUtil.verify(tokenStr, username, user.get Password())) {

log.info("登錄成功");

} else {

throw new UnknownAccountException("用戶名密碼錯(cuò)誤");

}

SimpleAuthenticationInfo simpleAuthenticationInfo= new SimpleAuthenticationInfo(token.getCredentials(),token.getCredentials(), this.getName());

return simpleAuthenticationInfo;

}

return null;

}

}

3.4 整合JWT實(shí)現(xiàn)

自定義JWT工具類,實(shí)現(xiàn)生成令牌、令牌驗(yàn)證、獲取對(duì)應(yīng)信息等相關(guān)功能。

public class JwtUtil {

private static final long EXPIRE_TIME = 60 *60 * 1000;

//校驗(yàn)token

public static boolean check(String token, String name, String secret) {

try {

//根據(jù)秘鑰生成JWT效驗(yàn)器

Algorithm alg = Algorithm.HMAC256(secret);

JWTVerifier verif = JWT.require(alg)

.withClaim("username", name)

.build();

//校驗(yàn)token

DecodedJWT dcjwt = verif.verify(token);

return true;

} catch (Exception e) {

return false;

}

}

//獲取用戶名

public static String getUsername(String token) {

try {

DecodedJWT jwt = JWT.decode(token);

return jwt.getClaim("username").asString();

} catch (JWTDecodeException e) {

return null;

}

}

//生成token

public static String sign(String uname, String secret) {

return JWT.create()

.withJWTId(UUID.randomUUID().toString())

.withClaim("username", uname)

.withExpiresAt(new Date(getCurrentDate()))

.sign(Algorithm.HMAC256(secret));

}

}

4 結(jié)語

本文通過對(duì)Apache Shiro、JWT、微服務(wù)架構(gòu)等技術(shù)的介紹與分析,提出了一種基于Apache Shiro的微服務(wù)認(rèn)證授權(quán)方案。方案在保留Shiro原有特性的前提下,實(shí)現(xiàn)了對(duì)微服務(wù)架構(gòu)的適配,具有高效率、高安全性、低耦合度、可擴(kuò)展等特點(diǎn)。方案所實(shí)現(xiàn)的安全框架能夠完成認(rèn)證授權(quán)在微服務(wù)架構(gòu)中的完全覆蓋,同時(shí)也保留了一定的靈活性,讀者可以根據(jù)實(shí)際情況調(diào)整安全框架的有效范圍,從而找到應(yīng)用整體的最佳運(yùn)行效果。

引用

[1]時(shí)子慶,劉金蘭,譚曉華.基于OAuth2.0的認(rèn)證授權(quán)技術(shù)[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2012,21(3):260-264.

[2]梁清華,胡安明.Apache Shiro框架在Web系統(tǒng)的安全應(yīng)用研究[J].電腦知識(shí)與技術(shù),2021,17(6):52-53.

[3]范展源,羅福強(qiáng).JWT認(rèn)證技術(shù)及其在WEB中的應(yīng)用[J].數(shù)字技術(shù)與應(yīng)用,2016(2):114.

猜你喜歡
用戶服務(wù)信息
服務(wù)在身邊 健康每一天
服務(wù)在身邊 健康每一天
服務(wù)在身邊 健康每一天
招行30年:從“滿意服務(wù)”到“感動(dòng)服務(wù)”
商周刊(2017年9期)2017-08-22 02:57:56
訂閱信息
中華手工(2017年2期)2017-06-06 23:00:31
關(guān)注用戶
商用汽車(2016年11期)2016-12-19 01:20:16
關(guān)注用戶
商用汽車(2016年6期)2016-06-29 09:18:54
關(guān)注用戶
商用汽車(2016年4期)2016-05-09 01:23:12
如何獲取一億海外用戶
展會(huì)信息
主站蜘蛛池模板: 中日无码在线观看| 久久婷婷国产综合尤物精品| 国产女人在线观看| 91口爆吞精国产对白第三集| 狠狠v日韩v欧美v| 国产成人精品日本亚洲| 亚洲看片网| 99re在线观看视频| 露脸国产精品自产在线播| 熟女日韩精品2区| 最新日韩AV网址在线观看| 国产www网站| 天天综合色天天综合网| 欧美yw精品日本国产精品| 亚洲欧美另类视频| 欧美日本激情| 九色最新网址| 中文字幕在线看| 丰满少妇αⅴ无码区| 国产主播在线一区| 成人免费黄色小视频| 国产成人精品一区二区| 无码日韩精品91超碰| 久久福利片| 波多野结衣一二三| 欧美三級片黃色三級片黃色1| 黄色污网站在线观看| 久久综合伊人 六十路| 日本一本在线视频| 草草线在成年免费视频2| 亚洲中文字幕久久无码精品A| аⅴ资源中文在线天堂| 欧美中文一区| 精品久久蜜桃| 秘书高跟黑色丝袜国产91在线| 成人小视频网| 亚洲色精品国产一区二区三区| 欧美a级在线| 国产精品综合久久久| 国产成人8x视频一区二区| 国产一级毛片高清完整视频版| 狠狠躁天天躁夜夜躁婷婷| 99精品高清在线播放| 日韩天堂网| 国产AV无码专区亚洲精品网站| 国产欧美日韩免费| 久久国产精品夜色| 国产精品丝袜在线| 四虎永久免费网站| 婷婷午夜影院| 久久精品波多野结衣| 免费一极毛片| 欧美日韩综合网| 成人免费一级片| 五月婷婷综合在线视频| 午夜一级做a爰片久久毛片| 亚洲色图在线观看| 亚洲系列无码专区偷窥无码| 国产第一页亚洲| 天堂中文在线资源| 国产精品自在在线午夜| 亚洲狠狠婷婷综合久久久久| 在线欧美日韩| 国产成人精品在线| 中文字幕1区2区| 色综合中文| 日日摸夜夜爽无码| 国产精品中文免费福利| 97青草最新免费精品视频| 中文字幕日韩欧美| 日日碰狠狠添天天爽| 亚洲av色吊丝无码| 美女高潮全身流白浆福利区| 天天综合网色中文字幕| 99精品在线视频观看| 国产日韩精品一区在线不卡| 免费在线a视频| 伊人天堂网| 欧美日韩第二页| 最新午夜男女福利片视频| 欧美成人一区午夜福利在线| 亚洲成网777777国产精品|