废话少说,上视频
spring boot 之 kotlin用一次就想放弃java,爽歪歪~~~
1、启动入口:
@SpringBootApplication
@EnableDiscoveryClient
class TawuziAuthServerDbApplication
fun main(args: Array<String>) {
runApplication<TawuziAuthServerDbApplication>(*args)
}
说明
kotlin中的method,语法为
fun 函数名(参数1,参数2): 返回值 {
函数体
}
是不是比Java简单了
2、控制器controller:
@Controller
class MessagesController {
@ResponseBody
@GetMapping("/messages")
fun getMessages(): Array<String>? {
return arrayOf("Message 1", "Message 2", "Message 3")
}
@ResponseBody
@GetMapping("/user")
fun user(): Jwt? {
val principal = SecurityContextHolder.getContext().authentication.principal as Jwt
println(principal)
// 查询数据库获取用户信息
return principal
}
}
3、依赖注入:
类与方法参数均可注入
@Configuration(proxyBeanMethods = false)
class AuthorizationServerConfig(
@Autowired val passwordEncoder: PasswordEncoder,
@Value("\${diy.secure.jwk.fpath}") val jwkFile: String,
@Value("\${diy.secure.jwk.keypass}") val jwkKeypass: String,
@Value("\${diy.secure.jwk.storepass}") val jwkStorepass: String,
@Value("\${diy.secure.jwk.alias}") val jwkAlias: String
) {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@Throws(
Exception::class
)
fun authorizationServerSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
val authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer()
authorizationServerConfigurer
.authorizationEndpoint { authorizationEndpoint ->
authorizationEndpoint
.consentPage(CUSTOM_CONSENT_PAGE_URI)
}
.oidc(Customizer.withDefaults())
val endpointsMatcher: RequestMatcher = authorizationServerConfigurer.endpointsMatcher
http
.csrf().disable().cors().disable()
.securityMatcher(endpointsMatcher)
.authorizeHttpRequests {authorize ->
authorize
// .requestMatchers("/auth/.well-known/**").permitAll()
.anyRequest().authenticated()
}
.csrf {csrf ->
csrf.ignoringRequestMatchers(endpointsMatcher)
}
.exceptionHandling {exceptions ->
exceptions.authenticationEntryPoint(LoginUrlAuthenticationEntryPoint("/login"))
}
.oauth2ResourceServer { obj ->
obj.jwt()
}.apply(authorizationServerConfigurer)
return http.build()
}
// @formatter:off
@Bean
fun registeredClientRepository(jdbcTemplate: JdbcTemplate?): RegisteredClientRepository {
val registeredClient: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client")
.clientSecret("{noop}secret")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc")
.redirectUri("http://127.0.0.1:8080/authorized")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build())
.build()
val registeredClient1: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client1")
.clientSecret(passwordEncoder.encode("secret"))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8081/login/oauth2/code/messaging-client-oidc1")
.redirectUri("http://127.0.0.1:8081/authorized")
.redirectUri("http://127.0.0.1:8081/code")
.redirectUri("http://127.0.0.1:8081/cb")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(
ClientSettings
.builder()
.requireAuthorizationConsent(false)
.build()
)
.build()
val registeredClient4: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client4")
.clientSecret(passwordEncoder.encode("secret"))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:8084/login/oauth2/code/messaging-client-oidc4")
.redirectUri("http://127.0.0.1:8084/authorized")
.redirectUri("http://127.0.0.1:8084/backcb")
.redirectUri("http://127.0.0.1:8084/cb")
.redirectUri("http://127.0.0.1:8084/code")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(
ClientSettings
.builder()
.requireAuthorizationConsent(false)
.build()
)
.build()
val mobileRegisteredClient4: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("mobile-messaging-client4")
.clientSecret(passwordEncoder.encode("secret"))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://192.168.1.6:8100/login/oauth2/code/mobile-messaging-client-oidc4")
.redirectUri("http://192.168.1.6:8100/authorized")
.redirectUri("http://192.168.1.6:8100/backcb")
.redirectUri("http://192.168.1.6:8100/cb")
.redirectUri("http://192.168.1.6:8100/code")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(
ClientSettings
.builder()
.requireAuthorizationConsent(false)
.build()
)
.build()
val registeredClientLogin: RegisteredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("messaging-client-login")
.clientSecret(passwordEncoder.encode("secret"))
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.redirectUri("http://127.0.0.1:9010/login/oauth2/code/messaging-client-oidc-login")
.redirectUri("http://127.0.0.1:9010/authorized")
.redirectUri("http://127.0.0.1:9010/code")
.redirectUri("http://127.0.0.1:9010/cb")
.scope(OidcScopes.OPENID)
.scope(OidcScopes.PROFILE)
.scope("message.read")
.scope("message.write")
.clientSettings(
ClientSettings
.builder()
.requireAuthorizationConsent(false)
.build()
)
.build()
val registeredClientRepository = JdbcRegisteredClientRepository(jdbcTemplate)
return registeredClientRepository
}
// @formatter:on
@Bean
fun authorizationService(
jdbcTemplate: JdbcTemplate?,
registeredClientRepository: RegisteredClientRepository?
): OAuth2AuthorizationService {
return JdbcOAuth2AuthorizationService(jdbcTemplate, registeredClientRepository)
}
@Bean
fun authorizationConsentService(
jdbcTemplate: JdbcTemplate?,
registeredClientRepository: RegisteredClientRepository?
): OAuth2AuthorizationConsentService {
return JdbcOAuth2AuthorizationConsentService(jdbcTemplate, registeredClientRepository)
}
@Bean
@Throws(Exception::class)
fun jwkSource(): JWKSource<SecurityContext> {
val keyStore = KeyStore.getInstance(
ClassPathResource(
jwkFile!!
).file, jwkStorepass!!.toCharArray()
)
val rsaKey: RSAKey = RSAKey.load(keyStore, jwkAlias, jwkStorepass.toCharArray())
return JWKSource<SecurityContext> { jwkSelector: JWKSelector, securityContext: com.nimbusds.jose.proc.SecurityContext? ->
jwkSelector.select(
JWKSet(rsaKey)
)
}
}
@Bean
fun jwtDecoder(jwkSource: JWKSource<com.nimbusds.jose.proc.SecurityContext?>?): JwtDecoder {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource)
}
@Bean
fun authorizationServerSettings(): AuthorizationServerSettings {
return AuthorizationServerSettings.builder().issuer("http://banang.com:9000").build()
}
companion object {
private const val CUSTOM_CONSENT_PAGE_URI = "/oauth2/consent"
}
}
总结:
kotlin、flutter、Swift语言,差不多算是最近几年新出得语言,
虽然Google、苹果、jetbrains都在强力推荐新语言,
致力于将各自的语言应用到移动、服务器、前端等领域,
但从目前发展来看,kotlin无疑是发展最好的,
已经可以实现在Android、iOS端、web端(替换Java)稳定开发。
如果行业都在跟进的话,不出三年,Java有可能走向衰落。
Stay curious and keep learning。