Kotlin和Spring安全

SpringSecurity是一個令人驚奇的項目–它解決了業內一些最困難的問題,並幫助人們保護他們的應用程序。而且,似乎這還不夠,它顯示了堅定的決心,以確保安全容易。如果您在最早的版本中使用過SpringSecurity,您就會知道它需要負載爲了完成任何事情。這一點得到了改進,在SpringSecurity 3中,您可以使用XML的一兩個節來鎖定具有常識的默認應用程序。然後,在SpringSecurity4中,他們引入了一個JavaDSL,它使人們能夠通過編譯器來幫助他們驗證事情。隨着時間的推移,SpringSecurity也逐漸引入了常識缺省。現在,您可以註冊一個UserDetailsServiceSpringSecurity將鎖定基於servlet的HTTP應用程序中的所有HTTP端點,並需要身份驗證。再簡單不過了!或者可以?在SpringSecurity5.2中,他們引入了對SpringSecurity的一些備受讚賞的改進。現在,除了使用以前的FluidJava配置DSL之外,還有一種新的方法,您可以提供lambda併爲其提供上下文對象,然後您可以使用它。您不再需要縮進您的SpringSecurityAPI來理解它們的意圖了!現在,在這篇文章中,我們將以非常快的速度查看全新的SpringSecurityKotlinDSL。

請記住,SpringSecurity解決了兩個正交問題:身份驗證和授權。身份驗證回答了以下問題:“誰提出請求嗎?“是Josh,還是Jane?授權回答了一個問題:”請求者在系統內擁有什麼權限?“身份驗證完全是爲了插入身份提供程序。有無數種方法(ActiveDirectory、內存中的用戶名和密碼、LDAP、SAML等)–更多的是插入實現。我們只打算使用內存中的用戶名和密碼認證管理器,因爲我們需要它,而且DSL並不是真正的亮點。”

DSL最有用的不是用於交換給定類型的實現,而是用於描述規則或自定義行爲。因此,我們將使用SpringSecurityDSL自定義授權行爲。

下面是一個使用SpringSecurity的基於SpringBoot的應用程序。我從彈簧起爆它使用Kotlin,並使用SpringSecurity和SpringBoot2.3.M2或更高版本。它使用Functionalbean註冊DSL來編程註冊bean。我們討論了程序bean註冊。在.彈簧尖2017年waaaay的視頻。當然,該視頻演示了它在Java中的使用,但是應用程序在Kotlin中基本上是一樣的:通過將bean包裝爲調用bean功能。

第一個bean是InMemoryUserDetailsManager。第二個bean是一個功能性HTTP端點,/greetings。當HTTP請求傳入時,我們從當前請求中提取經過身份驗證的主體,提取名稱,然後構建一個ServerResponse其身體將由一個Map<String,String>.

有趣的是這個類KotlinSecurityConfiguration。它擴展了WebSecurityConfigurerAdapter。有幾種方法我們可以在那裏重寫,但是我選擇了覆蓋configure方法來指定兩件事:我想選擇加入HTTP基本身份驗證,並指定哪些路由需要身份驗證,哪些路由是廣泛開放的。下面的配置規定所有請求/greetings/()/greetings/端點,以及它下面的任何東西,比如/greetings/foo)必須經過認證。第二條規則是,其他一切都是開放的。非常重要的是更具體的規則-/greetings/-到更開放的規則前來.規則按順序從上到下進行評估。如果我們把第二條規則放在第一位,那麼它就會匹配每個請求,我們就不需要對規則進行評估了。/greetings-它實際上是完全開放的!

package com.example.kotlinsecurity
2
3
import org.springframework.boot.autoconfigure.SpringBootApplication
4
import org.springframework.boot.runApplication
5
import org.springframework.context.annotation.Bean
6
import org.springframework.context.support.beans
7
import org.springframework.security.config.annotation.web.builders.HttpSecurity
8
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
9
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
10
import org.springframework.security.config.web.servlet.invoke
11
import org.springframework.security.core.userdetails.User
12
import org.springframework.security.provisioning.InMemoryUserDetailsManager
13
import org.springframework.web.servlet.function.ServerResponse
14
import org.springframework.web.servlet.function.router
15
16
@SpringBootApplication
17
class KotlinSecurityApplication
18
19
@EnableWebSecurity
20
class KotlinSecurityConfiguration : WebSecurityConfigurerAdapter() {
21
22
    override fun configure(http: HttpSecurity?) {
23
        http {
24
            httpBasic {}
25
            authorizeRequests {
26
                authorize("/greetings/**", hasAuthority("ROLE_ADMIN"))
27
                authorize("/**", permitAll)
28
            }
29
        }
30
    }
31
}
32
33
fun main(args: Array<String>) {
34
    runApplication<KotlinSecurityApplication>(*args) {
35
        addInitializers(beans {
36
            bean {
37
38
                fun user(user: String, pw: String, vararg roles: String) =
39
                    User.withDefaultPasswordEncoder().username(user).password(pw).roles(*roles).build()
40
41
                InMemoryUserDetailsManager(user("jlong", "pw", "USER"), user("rwinch", "pw1", "USER", "ADMIN"))
42
            }
43
            bean {
44
                router {
45
                    GET("/greetings") { request ->
46
                        request.principal().map { it.name }.map { ServerResponse.ok().body(mapOf("greeting" to "Hello, $it")) }.orElseGet { ServerResponse.badRequest().build() }
47
                    }
48
                }
49
            }
50
        })
51
    }
52
}

結語

在本期文章中,我們介紹了SpringSecurity的新Kotlin DSL。有比代碼更多的文本,因爲SpringSecurity做了一個羅得所以API的表面積實際上是您想要進行的自定義的最小值,而不是已經合理的默認設置。我希望你學到了一些新東西,並且會給SpringSecurityDSL一個機會。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章