1. 首页 > 快讯

使用 Spring Security 保护 Spring Cloud 微服务

[[429798]]

在我之前的文章中,我对资源服务器进行了简单的说明,让大家对资源服务器的概念有一个简单的了解。今天我将通过一个实际的例子来演示单个应用改造为Spring Cloud微服务时资源服务器的实现。

资源服务器改造

以Spring Security实用资料DEMO为例。本来是一个单一的应用,认证和授权都是在一个应用中使用的。转型为独立服务后,原有的身份验证将被剥离(稍后我们将讨论如何实现),服务将仅保留基于用户凭证(JWT)的访问控制功能。接下来我们将逐步实现这个能力。

所需依赖

基于Spring Security,我们需要添加新的依赖项来支持OAuth2资源服务器和JWT。我们需要引入以下依赖库:

org.springframework.bootspring-boot-starter-security--resource-server--org.springframework.securityspring-security-oauth2-resource-server--jose--org.springframework.securityspring-security-oauth2-joseSpring安全5。 x 删除了OAuth2.0授权服务器,保留了OAuth2.0资源服务器。

JWT解码

要验证JWT,您必须实现JWT 解码功能。在Spring Security OAuth2资源服务器模块中,默认提供了一个解码器。该解码器需要根据以下条件调用:

spring.security.oauth2.resourceserver 配置下的元数据用于生成解码配置。这里的配置大部分是调用授权服务器打开的众所周知的断点,包括一系列用于解析和验证JWT的参数:

jwkSetUri一般是授权服务器提供的众所周知的端点,用于获取JWK配置,用于验证JWT Token。 jwsAlgorithm 指定jwt使用的算法,默认为RSA-256。 IssuerUri 获取OAuth2.0授权服务器元数据的端点。 publicKeyLocation 是用于解码的公钥路径。作为资源服务器,它只能持有公钥,不应该持有私钥。为了实现平滑过渡,一定不能使用默认配置,需要定制一个JWT解码器。接下来我们将逐步实施。

分离公私钥

资源服务器只能保存公钥,所以需要从之前的jks文件中导出一个公钥。

keytool-export-aliasfelordcn-keystore-file 导出cer 的完整路径。例如:

keytool-export-aliasfelordcn-keystoreD:\keystores\felordcn.jks-filed:\keystores\publickey.cer 将分离后的cer公钥文件放在原jks文件的路径下,资源服务器不再保存jks。

自定义jwt解码器

spring-security-oauth2-jose 是Spring Security 的jose 规范依赖项。我将基于这个库实现一个自定义JWT 解码器。

/***基于Nimbus的jwt解码器,并添加一些自定义验证策略**@paramvalidatorthevalidator*@returnthejwtdecoder*/@SneakyThrows@BeanpublicJwtDecoderjwtDecoder(@Qualifier('delegatingTokenValidator')DelegatingOAuth2TokenValidatorvalidator){CertificateFactorycertificateFactory=CertificateFactory.getInstance('X. 509');//从classpath路径中读取cer公钥证书来配置解码器ClassPathResourceresource=newClassPathResource(this.jwtProperties.getCertInfo().getPublicKeyLocation());Certificatecertificate=certificateFactory.generateCertificate(resource.getInputStream() } Some验证策略已经定制了,不得不说Nimbus的jwt类库比jjwt好用多了。

自定义资源服务器配置

接下来配置资源服务器。

核心流程和概念

资源服务器实际上配置了一个过滤器BearerTokenAuthenticationFilter来拦截和验证Bearer Token。验证通过且权限符合要求则发布;如果不通过,则不会发布。

与之前不同的是,验证成功后,凭证不再是UsernamePasswordAuthenticationToken 而是JwtAuthenticationToken:

@TransientpublicclassJwtAuthenticationTokenextendsAbstractOAuth2TokenAuthenticationToken{privatestaticfinallongserialVersionUID=SpringSecurityCoreVersion.SERIAL_VERSION_UID;privatefinalStringname;/***使用提供的参数构造{@codeJwtAuthenticationToken}。*@paramjwttheJWT*/publicJwt AuthenticationToken(Jwtjwt){super(jwt);this.name=jwt.getSubject();}/***使用提供的参数构造{@codeJwtAuthenticationToken}。*@paramjw ttheJWT*@paramauthoritiestheauthorities指派给JWT*/publicJwtAuthenticationToken(Jwtjwt,Collection?extendsGrantedAuthorityauthorities){超级(jw t,authorities);this.setAuthenticated(true);this.name=jwt.getSubject();}/***使用提供的参数构造{@codeJwtAuthenticationToken}。*@par amjwttheJWT*@paramauthoritiestheauthorities分配给JWT*@paramnametheprincipalname*/publicJwtAuthenticationToken(Jwtjwt,集合?扩展格兰特dAuthorityauthorities,Stringname){super(jwt,authorities);this.setAuthenticated(true);this.name=name;}@OverridepublicMapgetTokenAttributes(){return his.getToken().getClaims();}/***子值jwt中的username比较合适*/@OverridepublicStringgetName(){returnthis.name;}}我们在转换的时候要特别注意这一点,尤其是从SecurityContext中获取用户凭证信息时。

资源管理器配置

从Spring Security 5某个版本开始,不需要集成适配类。只需要这样配置Spring Security即可。对于资源管理器也是如此:

@BeanSecurityFilterChainjwtSecurityFilterChain(HttpSecurityhttp)throwsException{returnhttp.authorizeRequests(request-request.anyRequest().access('@checker.check(authentication,request)')).exceptionHand ling().accessDeniedHandler(newSimpleAccessDeniedHandler()).authenticationEntryPoint(newSimpleAuthenticationEntryPoint()).and().oauth2ResourceServer(OAuth2ResourceServerConfigurer:jwt).build();}

JWT个性化解析

完成从JWT Token解析数据并生成JwtAuthenticationToken的操作通过JwtAuthenticationConverter。您可以自定义此转换器来实现一些个性化的功能。例如,默认情况下,解析的权限以SCOPE_为前缀,项目中使用ROLE_。您可以使用此类来兼容旧项目。

@BeanJwtAuthenticationConverterjwtAuthenticationConverter(){JwtAuthenticationConverterjwtAuthenticationConverter=newJwtAuthenticationConverter();JwtGrantedAuthoritiesConverterjwtGrantedAuthoritiesConverter=newJwtGrantedAuthoritiesConverter();//如果没有按照规范解析权限集合Authorities,则需要自定义key//jwtGrantedAuthoritiesConverter.setAuthoritiesClaimName('s copes');//OAuth2默认前缀是SCOPE_SpringSecurity是ROLE_jwtGrantedAuthoritiesConverter.setAuthorityPrefix('');jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(jwtGrantedAuthoritiesConverter);//设置用户名的默认key在jwt 中是sub。您可以自定义jwtAuthenticationConverter.setPrincipalClaimName(JwtClaimNames.SUB); returnjwtAuthenticationConverter;} 到这里转换就基本完成了。您的受保护资源API 将受到Bearer Token 的保护。

实际生产中,建议将资源服务器封装为依赖,集成到需要保护资源的服务中。

附加说明

要测试资源服务器,假设我们有一个颁发令牌的授权服务器。这里简单模拟一个发币方法获取Token:

/***资源服务器不应生成JWT,但出于测试目的,假定它是身份验证服务器*/@SneakyThrows@TestpublicvoidimitateAuthServer(){JwtEncoderjwsEncoder=newNimbusJwsEncoder(jwkSource());JwtTokenGeneratorjwtTokenGenerator=newJwtTokenGenerator(jwsEncoder);OAuth2AccessTokenResponseoAuth2Ac cessTokenResponse=jwtTokenGenerator.tokenResponse() ;System.out.println('oAuth2AccessTokenResponse='+oAuth2AccessTokenResponse.getAccessToken().getTokenValue());}@SneakyThrowsprivateJWKSourcejwkSource(){ClassPathResourceresource=newClassPathResource('felordcn.jks');KeyStorejks=KeyStore. getInstance('jks') ;Stringpass='123456';char[]pem=pass.toCharArray();jks.load(resource.getInputStream(),pem);RSAKeyrsaKey=RSAKey.load(jks,'felordcn',pem );JWKSetjwkSet=newJWKSet( rsaKey);returnnewImmutableJWKSet(jwkSet);}

好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!

用户评论

金橙橙。-

Spring Security真是太棒了!终于可以用它来保护我的微服务资源了。

    有12位网友表示赞同!

眷恋

一直在寻找一种安全的方法管理我们的微服务,这篇文章看起来很有帮助。

    有19位网友表示赞同!

无关风月

这篇博客讲解的非常清晰,能让我更好地理解资源服务器的工作原理。

    有8位网友表示赞同!

艺菲

看来Spring Security和Spring Cloud很搭在一起,这下安全性有了保证。

    有8位网友表示赞同!

凉话刺骨

资源服务器是个好东西,可以把权限控制做得更细致化。

    有20位网友表示赞同!

嘲笑!

我以前没有了解过资源服务器,这篇文章让我对它有了一些概念。

    有9位网友表示赞同!

铁树不曾开花

学习一下Spring Security的实践案例总是很值钱的。

    有6位网友表示赞同!

闷骚闷出味道了

需要好好读一读这篇文章,提升一下微服务的安全性水平。

    有20位网友表示赞同!

╭摇划花蜜的午后

终于有人把Spring Security和微服务结合了,非常期待后续的发展。

    有11位网友表示赞同!

看我发功喷飞你

对安全性的需求越来越高,这样的人工智能时代才能更放心。

    有6位网友表示赞同!

白恍

资源服务器可以帮我更好地控制哪些数据可以被访问,太方便了!

    有18位网友表示赞同!

哭花了素颜

我正在学习微服务开发,这篇文章对我来说非常有价值。

    有12位网友表示赞同!

娇眉恨

想了解一下如何使用Spring Security的安全策略来保护我的应用。

    有8位网友表示赞同!

怀念·最初

Spring Cloud的生态系统越来越丰富了,现在微服务的安全性更不用担心了。

    有5位网友表示赞同!

爱情的过失

看来这种资源服务器的模式很有潜力,可以让我更有信心去开发微服务。

    有5位网友表示赞同!

Edinburgh°南空

要好好学习一下微服务架构的安全最佳实践,这篇文章能给我一些启发。

    有15位网友表示赞同!

闲肆

以后应该多关注Spring Security新特性,提高自身的技能水平。

    有8位网友表示赞同!

夏至离别

越来越多的工具和技术可以帮助我们打造安全可靠的微服务系统。

    有9位网友表示赞同!

旧爱剩女

学习新的技术总是很 exciting, 这篇文章正好让我开阔视野。

    有12位网友表示赞同!

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7408.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666