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<User> 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) 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配置或执行器的安全性)。

要关闭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=https://my-redirect-uri.com
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=https://my-redirect-uri.com
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=https://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=https://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name

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

spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/

默认情况下,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=https://example.com/oauth2/default/v1/keys
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/

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

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

 

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

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

spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://example.com/check-token
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=https://remoteidp1.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=https://remoteidp2.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安全参考指南中找到。
 
 

猜你喜欢

转载自www.cnblogs.com/muxi0407/p/12077448.html