试图理解 kotlin 对象代码块

Trying to understand kotlin object code block

我想了解以下代码片段:

@Bean
fun securityWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain? {
    val customPrincipalExtractor = SubjectDnX509PrincipalExtractor()
    customPrincipalExtractor.setSubjectDnRegex("OU=(.*?)(?:,|$)")
    val customAuthenticationManager = ReactiveAuthenticationManager { authentication: Authentication ->
        authentication.isAuthenticated = "Trusted Org Unit" == authentication.name
        Mono.just(authentication)
    }
    return http {
        x509 {
            principalExtractor = customPrincipalExtractor
            authenticationManager = customAuthenticationManager
        }
        authorizeExchange {
            authorize(anyExchange, authenticated)
        }
    }
}

来自 https://docs.spring.io/spring-security/reference/5.6.1/reactive/authentication/x509.html.

我的问题是这个块是什么意思?

http {
    x509 {
        principalExtractor = customPrincipalExtractor
        authenticationManager = customAuthenticationManager
    }
    authorizeExchange {
        authorize(anyExchange, authenticated)
    }
}

它是如何工作的?

您询问的代码配置 spring 安全性。您有一个名为 httpServerHttpSecurity 对象,您正在对其进行配置。

它在常规 java 中等于:

http
    .x509()
        .principalExtractor(customPrincipalExtractor)
        .authenticationManager(customAuthenticationManager)
    .authorizeExchange()
        .anyExchange()
        .authenticated();

前三行表示我们将使用 x509 证书,我们有一个自定义的委托人提取器,我们定义了几行以上的 SubjectDnX509PrincipalExtractor https://docs.spring.io/spring-security/site/docs/3.2.8.RELEASE/apidocs/org/springframework/security/web/authentication/preauth/x509/SubjectDnX509PrincipalExtractor.html 需要当我们从证书中提取信息并构建主体对象时使用(所有用户在通过身份验证后都有一个主体,其中包含他们的身份等)

那个特定的提取器使用正则表达式提取证书中定义的subject

之后的行我们设置了自定义 AuthenticationManager https://javadoc.io/doc/org.springframework.security/spring-security-core/latest/org/springframework/security/authentication/AuthenticationProvider.html

spring 内置了其中的几个。例如,如果您想使用用户名和密码进行身份验证,或者通过提供令牌或 cookie,或者通过提供证书,您可以使用特定的身份验证管理器。或者,如果您想以特定方式验证某人的身份,您可以编写自定义的。

最后三行表示任何交换(请求)都需要进行身份验证。

这叫做type-safe builder pattern。它在 Kotlin 中主要用于声明式地创建对象 and/or 由库提供 DSL。它是 Kotlin 最高级的特性之一,所以用几句话解释起来并不容易,但上面的例子是这样工作的:

  1. http() 是一个 higher-order 函数,它接收用于配置 http 对象的 lambda。
  2. http() 执行此 lambda,为 lambda 提供某种“http 范围”或“http 构建器”对象。 Lambda 以 this 的形式接收此参数,因此我们可以隐式访问其成员。 (不知道这个scope/builder对象的具体类型是什么,可以通过http上的control-clicking查看)
  3. Lambda 可以配置 http 通过访问提供的 scope/builder 成员创建的对象。 x509()authorizeExchange() 是构建器的成员或它的扩展。我们可以在 http {} 块内无处不在地调用它们,因为构建器是我们的 this,所以它的所有成员都被隐式解析。
  4. x509()authorizeExchange()http() 做同样的事情。他们接受 lambda 并为 lambda 提供另一个构建器。