技术好文:SpringBoot学习(五)RSocket和Security

简介: 技术好文:SpringBoot学习(五)RSocket和Security

一、RSocket


RSocket是一个用于字节流传输的二进制协议。它通过在单个连接上传递异步消息来支持对称交互模型,主要支持的通讯层包括 TCP, WebSockets和Aeron(UDP)。


RSocket主要采用异步消息模型进行通讯,通过单一连接解决所有的异步消息交换。主要包括以下通讯模型:


request/response:请求/响应,发出一个请求,获取一个响应


request/stream:请求/流式响应,一个请求对应多个/无数个流式的响应


fire-and-forget:异步触发,不需要响应


channel (bi-directional streams):双向异步通讯,也就是channel的支持


Spring框架的Spring消息传递模块在客户端和服务器端为RSocket请求程序和响应程序提供支持。有关更多细节,请参阅Spring框架参考中的RSocket部分,包括RSocket协议的概述。


1.1RSocket策略自动配置


Spring Boot自动配置RSocketStrategies bean,它提供了编码和解码RSocket有效负载所需的所有基础设施。默认情况下,自动配置将尝试配置以下(按顺序):


a.Jackson的CBOR解码器


b.Jackson的JSON解码器


spring-boot-starter-rsocket启动器提供了这两个依赖项。


开发人员可以通过创建实现rsocketstrateescustomizer接口的bean来定制RSocketStrategies组件。注意它们的@Order很重要,因为它决定了编解码器的顺序。


1.2RSocket服务器自动配置


Spring Boot提供RSocket服务器自动配置。所需的依赖项由spring-boot-starter-rsocket提供。


Spring Boot允许从WebFlux服务器通过WebSocket暴露RSocket,或者支持独立的RSocket服务器。这取决于应用程序的类型及其配置。


对于WebFlux应用程序(即类型为WebApplicationType.REACTIVE), RSocket服务器只有在下列属性匹配时才会被插入到Web服务器:


spring.rsocket.server.mapping-path=/rsocket # a mapping path is defined


spring.rsocket.server.transport=websocket # websocket is chosen as a transport


#spring.rsocket.server.port= # no port is defined


注:只有Reactor Netty才支持将RSocket插入web服务器,因为RSocket本身就是用这个库构建的。


或者,将RSocket TCP或websocket服务器作为独立的嵌入式服务器启动。除了依赖需求,唯一需要的配置是为该服务器定义一个端口:


spring.rsocket.server.port=9898 # the only required configuration


spring.rsocket.server.transport=tcp # you're free to configure other properties


1.3Spring消息传递RSocket支持


Spring Boot将自动为RSocket配置Spring消息传递基础结构。


这意味着Spring Boot将创建一个RSocketMessageHandler bean,用于处理应用程序的RSocket请求。


1.4使用RSocketRequester调用RSocket服务


一旦服务器和客户机之间建立了RSocket通道,任何一方都可以向另一方发送或接收请求。


作为服务器,可以在RSocket @Controller的任何处理程序方法上注入RSocketRequester实例。作为客户端,首先需要配置和建立RSocket连接。Spring Boot自动配置一个RSocketRequester。使用预期的编解码器构建此类情况。


RSocketRequester.Builder实例是一个原型bean,这意味着每个注入点都将为您提供一个新实例。这样做是有目的的,因为这个构建器是有状态的,您不应该使用同一个实例创建具有不同设置的请求程序。


下面的代码展示了一个典型的例子:


@Service


public class MyService {


private final RSocketRequester rsocketRequester;


public MyService(RSocketRequester.Builder rsocketRequesterBuilder) {


this.rsocketRequester = rsocketRequesterBuilder


.connectTcp("example.org", 9898).block();


}


public Mono someRSocketCall(String name) {


return this.requester.route("user").data(name)


.retrieveMono(User.class);


}


}


二、安全


如果类路径上有Spring Security,那么默认情况下web应用程序是安全的。Spring Boot依赖于Spring Security的内容协商策略来决定是使用httpBasic还是formLogin。要将方法级安全性添加到web应用程序,您还可以使用所需的设置添加@EnableGlobalMethodSecurity。其他信息可以在Spring安全参考指南中找到。


默认的UserDetailsService只有一个用户。用户名是user,密码是随机的,在应用程序启动时在INFO级别打印,如下例所示:


Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35


注:如果对日志配置进行了微调,请确保org.springframe .boot.autoconfigure.security类别设置为INFO级别消息。否则,将不打印默认密码。


您可以通过提供spring.security.user.name和spring.security.user.password来更改用户名和密码。


默认情况下,web应用程序的基本特性如下:


a.一个UserDetailsService(或WebFlux应用程序中的ReactiveUserDetailsService) //代码效果参考:http://hnjlyzjd.com/hw/wz_25096.html

bean,它具有内存存储和一个用户生成的密码(参见用户属性SecurityProperties.User)。

b.整个应用程序的基于表单的登录或HTTP基本安全(取决于请求中的Accept标头)(包括执行器端点,如果执行器位于类路径上)。


c.用于发布身份验证事件的DefaultAuthenticationEventPublisher。


您可以通过为它添加一个bean来提供一个不同的AuthenticationEventPublisher。


1.MVC安全


默认的安全配置是在SecurityAutoConfiguration和UserDetailsServiceAutoConfiguration中实现的。SecurityAutoConfiguration为web安全和UserDetailsServiceAutoConfiguration配置身份验证,这也与非web应用程序相关。要完全关闭默认的web应用程序安全配置,或组合多个Spring安全组件(如OAuth 2客户端和资源服务器),请添加WebSecurityConfigurerAdapter类型的bean(这样做不会禁用UserDetailsService配置或执行器的安全性)。


要关闭UserDetailsService配置,您可以添加UserDetailsService、AuthenticationProvider或AuthenticationManager类型的bean。


可以通过添加自定义的WebSecurityConfigurerAdapter来覆盖访问规则。Spring Boot提供了方便的方法,可用于覆盖执行器端点和静态资源的访问规则。EndpointRequest可以用来创建一个基于management.endpoints.web的请求匹配程序。基本路径属性。可以使用PathRequest为常用位置的资源创建一个RequestMatcher。


2.WebFlux安全


与Spring MVC应用程序类似,您可以通过添加Spring -boot-starter-security依赖项来保护WebFlux应用程序。默认的安全配置是在ReactiveSecurityAutoConfiguration和UserDetailsServiceAutoConfiguration中实现的。ReactiveSecurityAutoConfiguration为web安全和UserDetailsServiceAutoConfiguration配置身份验证,这也与非web应用程序相关。要完全关闭默认的web应用程序安全配置,可以添加WebFilterChainProxy类型的bean(这样做不会禁用UserDetailsService配置或执行器的安全性)。


//代码效果参考: http://hnjlyzjd.com/xl/wz_25094.html

要关闭UserDetailsService配置,您可以添加类型为ReactiveUserDetailsService或ReactiveAuthenticationManager的bean。


通过添加一个定制的SecurityWebFilterChain bean,可以配置访问规则和使用多个Spring安全组件,如OAuth 2客户端和资源服务器。Spring Boot提供了方便的方法,可用于覆盖执行器端点和静态资源的访问规则。


EndpointRequest可以用来创建一个基于management.endpoints.web的management.endpoints.web.base-path属性。


可以使用PathRequest为常用位置的资源创建一个ServerWebExchangeMatcher。


例如,您可以通过添加以下内容来定制您的安全配置:


@Bean


public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {


return http


.authorizeExchange()


.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()


.pathMatchers("/foo", "/bar")


.authenticated().and()


.formLogin().and()


.build();


}


3.OAuth2


OAuth2是Spring支持的一个广泛使用的授权框架。


3.1客户端


如果您的类路径上有spring-security-oauth2-client,那么您可以利用一些自动配置来轻松设置OAuth2/Open ID连接客户机。这个配置使用了OAuth2ClientProperties下的属性。相同的属性适用于servlet和反应性应用程序。


您可以注册多个OAuth2客户机和在spring.security.oauth2.client前缀下的提供者。客户端前缀,如下例所示:


spring.security.oauth2.client.registration.my-client-1.client-id=abcd


spring.security.oauth2.client.registration.my-client-1.client-secret=password


spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope


spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider


spring.security.oauth2.client.registration.my-client-1.scope=user


spring.security.oauth2.client.registration.my-client-1.redirect-uri=


spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic


spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code


spring.security.oauth2.client.registration.my-client-2.client-id=abcd


spring.security.oauth2.client.registration.my-client-2.client-secret=password


spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope


spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider


spring.security.oauth2.client.registration.my-client-2.scope=email


spring.security.oauth2.client.registration.my-client-2.redirect-uri=


spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic


spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code


spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=


spring.security.oauth2.client.provider.my-oauth-provider.token-uri=


spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=


spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header


spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=


spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name


对于支持OpenID连接发现的OpenID连接提供程序,配置可以进一步简化。提供者需要配置一个发布方URI,该URI是其声明的发布方标识符。例如,如果提供的发布方uri是“那么将向“ - Configuration”发出一个OpenID提供者配置请求。预期结果是一个OpenID提供者配置响应。下面的示例展示了如何使用发布方uri配置OpenID连接提供程序:


spring.security.oauth2.client.provider.oidc-provider.issuer-uri=


默认情况下,Spring Security的OAuth2LoginAuthenticationFilter只处理匹配/login/oauth2/code/*的url。如果希望自定义redirect-uri以使用不同的模式,则需要提供配置来处理该自定义模式。例如,对于servlet应用程序,您可以添加自己的WebSecurityConfigurerAdapter,如下所示:


public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {


@Override


protected void configure(HttpSecurity http) throws Exception {


http


.authorizeRequests()


.anyRequest().authenticated()


.and()


.oauth2Login()


.redirectionEndpoint()


.baseUri("/custom-callback");


}


}


普通提供者的OAuth2客户端注册


对于常见的OAuth2和OpenID提供者,包括谷歌、Github、Facebook和Okta,我们提供了一组提供者缺省值(分别为谷歌、Github、Facebook和Okta)。


如果不需要自定义这些提供程序,则可以将提供程序属性设置为需要推断默认值的属性。另外,如果客户端注册的密钥与默认的受支持的提供者匹配,Spring Boot也会推断出这一点。


换句话说,下面示例中的两个配置使用了谷歌提供程序:


spring.security.oauth2.client.registration.my-client.client-id=abcd


spring.security.oauth2.client.registration.my-client.client-secret=password


spring.security.oauth2.client.registration.my-client.provider=google


spring.security.oauth2.client.registration.google.client-id=abcd


spring.security.oauth2.client.registration.google.client-secret=password


3.2资源服务器


如果您的类路径上有Spring -security- OAuth2 - Resource - Server, Spring Boot可以设置一个OAuth2资源服务器。对于JWT配置,需要指定JWK Set URI或OIDC发布方URI,如下例所示:


spring.security.oauth2.resourceserver.jwt.jwk-set-uri=


spring.security.oauth2.resourceserver.jwt.issuer-uri=


注:如果授权服务器不支持JWK设置的URI,您可以使用用于验证JWT签名的公钥来配置资源服务器。这可以使用spring.security.oauth2.resourceserver.jwt来完成。公钥位置属性,其中的值需要指向一个文件,该文件包含peme编码的x509格式的公钥。


相同的属性适用于servlet和反应性应用程序。


或者,您可以为servlet应用程序定义自己的JwtDecoder bean,或者为反应性应用程序定义ReactiveJwtDecoder。


在使用不透明令牌而不是JWTs的情况下,您可以配置以下属性来通过自省验证令牌:


spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=


spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id


spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret


同样,servlet和反应性应用程序都适用相同的属性。


或者,您可以为servlet应用程序定义自己的opaquetokenintrotor bean,或者为反应性应用程序定义一个reactiveopaquetokenintrotor。


3.3授权服务器


目前,Spring Security不支持实现OAuth 2.0授权服务器。但是,这个功能可以从Spring Security OAuth项目获得,Spring Security最终将完全取代它。在此之前,您可以使用spring-security- oau2 -autoconfigure模块轻松设置OAuth 2.0授权服务器;有关说明,请参阅其文档。


4.SAML 2.0


4.1依赖方


如果您的类路径上有spring-security-saml2-service-provider,那么您可以利用一些自动配置来简化SAML 2.0依赖方的设置。此配置使用Saml2RelyingPartyProperties下的属性。


依赖方注册表示身份提供者(IDP)和服务提供者(SP)之间的成对配置。您可以在spring.security.saml2下注册多个依赖方。重放方前缀,如下例所示:


spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials【0】.private-key-location=path-to-private-key


spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials【0】.certificate-location=path-to-certificate


spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.verification.credentials【0】.certificate-location=path-to-verification-cert


spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.entity-id=remote-idp-entity-id1


spring.security.saml2.relyingparty.registration.my-relying-party1.identityprovider.sso-url=


spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials【0】.private-key-location=path-to-private-key


spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials【0】.certificate-location=path-to-certificate


spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.verification.credentials【0】.certificate-location=path-to-other-verification-cert


spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.entity-id=remote-idp-entity-id2


spring.security.saml2.relyingparty.registration.my-relying-party2.identityprovider.sso-url=


5.致动器安全


出于安全考虑,除/health和/info之外的所有执行器默认都是禁用的。management.endpoints.web.exposure。include属性可用于启用执行器。


如果Spring Security在类路径上,并且没有其他WebSecurityConfigurerAdapter存在,那么除了/health和/info之外的所有执行器都由Spring引导自动配置来保护。如果你定义了一个自定义的WebSecurityConfigurerAdapter, Spring引导自动配置将后退,你将完全控制驱动器的访问规则。


注:在设置management.endpoints.web.exposure.include之前。确保暴露的执行器不包含敏感信息和/或通过将它们放置在防火墙后或通过Spring Security之类的东西来保护它们。


5.1跨站申请防伪保护


由于Spring Boot依赖于Spring Security的默认值,所以CSRF保护在默认情况下是打开的。这意味着,当使用默认的安全配置时,执行器端点需要POST (shutdown和loggers端点)、PUT或DELETE将得到403禁止错误。


注:我们建议只在创建非浏览器客户端使用的服务时才完全禁用CSRF保护。


有关CSRF保护的更多信息可以在Spring安全参考指南中找到。

相关文章
|
19天前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
95 2
|
12天前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
30 9
|
13天前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
16 1
|
17天前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
38 2
|
17天前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
39 1
|
17天前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
14 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
17天前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
16 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
17天前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
28 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
17天前
|
Java 关系型数据库 MySQL
springboot学习四:springboot链接mysql数据库,使用JdbcTemplate 操作mysql
这篇文章是关于如何使用Spring Boot框架通过JdbcTemplate操作MySQL数据库的教程。
17 0
springboot学习四:springboot链接mysql数据库,使用JdbcTemplate 操作mysql
|
17天前
|
Java 测试技术 Spring
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
这篇文章介绍了Spring Boot中配置文件的语法、如何读取配置文件以及如何通过静态工具类读取配置文件。
21 0
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件