Add jdbc storage for clients
This commit is contained in:
parent
b031d7f2f8
commit
bb4a6dc907
@ -20,6 +20,8 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")
|
implementation("org.springframework.boot:spring-boot-starter-oauth2-authorization-server")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
|
||||||
|
runtimeOnly("org.postgresql:postgresql")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
package ru.vyatsu.qr_access_auth_server
|
||||||
|
|
||||||
|
import org.springframework.security.oauth2.core.AuthorizationGrantType
|
||||||
|
import org.springframework.security.oauth2.core.ClientAuthenticationMethod
|
||||||
|
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository.RegisteredClientRowMapper
|
||||||
|
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient
|
||||||
|
import org.springframework.util.StringUtils
|
||||||
|
import java.sql.ResultSet
|
||||||
|
|
||||||
|
class KotlinRegisteredClientRowMapper : RegisteredClientRowMapper() {
|
||||||
|
|
||||||
|
override fun mapRow(rs: ResultSet, rowNum: Int): RegisteredClient? {
|
||||||
|
val clientIdIssuedAt = rs.getTimestamp("client_id_issued_at")
|
||||||
|
val clientSecretExpiresAt = rs.getTimestamp("client_secret_expires_at")
|
||||||
|
val clientAuthenticationMethods =
|
||||||
|
StringUtils.commaDelimitedListToSet(rs.getString("client_authentication_methods"))
|
||||||
|
val authorizationGrantTypes = StringUtils.commaDelimitedListToSet(rs.getString("authorization_grant_types"))
|
||||||
|
val redirectUris = StringUtils.commaDelimitedListToSet(rs.getString("redirect_uris"))
|
||||||
|
val postLogoutRedirectUris = StringUtils.commaDelimitedListToSet(rs.getString("post_logout_redirect_uris"))
|
||||||
|
val clientScopes = StringUtils.commaDelimitedListToSet(rs.getString("scopes"))
|
||||||
|
val builder = RegisteredClient.withId(rs.getString("id"))
|
||||||
|
.clientId(rs.getString("client_id"))
|
||||||
|
.clientIdIssuedAt(clientIdIssuedAt?.toInstant())
|
||||||
|
.clientSecret(rs.getString("client_secret"))
|
||||||
|
.clientSecretExpiresAt(clientSecretExpiresAt?.toInstant())
|
||||||
|
.clientName(rs.getString("client_name"))
|
||||||
|
.clientAuthenticationMethods { authenticationMethods ->
|
||||||
|
clientAuthenticationMethods.forEach { authenticationMethod ->
|
||||||
|
authenticationMethods.add(resolveClientAuthenticationMethod(authenticationMethod))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.authorizationGrantTypes { grantTypes ->
|
||||||
|
authorizationGrantTypes.forEach { grantType ->
|
||||||
|
grantTypes.add(resolveAuthorizationGrantType(grantType))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.redirectUris { uris -> uris.addAll(redirectUris) }
|
||||||
|
.postLogoutRedirectUris { uris ->
|
||||||
|
uris.addAll(postLogoutRedirectUris)
|
||||||
|
}
|
||||||
|
.scopes { scopes -> scopes.addAll(clientScopes) }
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveAuthorizationGrantType(authorizationGrantType: String): AuthorizationGrantType {
|
||||||
|
return if (AuthorizationGrantType.AUTHORIZATION_CODE.value == authorizationGrantType) {
|
||||||
|
AuthorizationGrantType.AUTHORIZATION_CODE
|
||||||
|
} else if (AuthorizationGrantType.CLIENT_CREDENTIALS.value == authorizationGrantType) {
|
||||||
|
AuthorizationGrantType.CLIENT_CREDENTIALS
|
||||||
|
} else {
|
||||||
|
if (AuthorizationGrantType.REFRESH_TOKEN.value == authorizationGrantType) AuthorizationGrantType.REFRESH_TOKEN
|
||||||
|
else AuthorizationGrantType(authorizationGrantType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resolveClientAuthenticationMethod(clientAuthenticationMethod: String): ClientAuthenticationMethod {
|
||||||
|
return if (ClientAuthenticationMethod.CLIENT_SECRET_BASIC.value == clientAuthenticationMethod) {
|
||||||
|
ClientAuthenticationMethod.CLIENT_SECRET_BASIC
|
||||||
|
} else if (ClientAuthenticationMethod.CLIENT_SECRET_POST.value == clientAuthenticationMethod) {
|
||||||
|
ClientAuthenticationMethod.CLIENT_SECRET_POST
|
||||||
|
} else {
|
||||||
|
if (ClientAuthenticationMethod.NONE.value == clientAuthenticationMethod) ClientAuthenticationMethod.NONE
|
||||||
|
else ClientAuthenticationMethod(clientAuthenticationMethod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.vyatsu.qr_access_auth_server
|
package ru.vyatsu.qr_access_auth_server
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import com.nimbusds.jose.jwk.JWKSet
|
import com.nimbusds.jose.jwk.JWKSet
|
||||||
import com.nimbusds.jose.jwk.RSAKey
|
import com.nimbusds.jose.jwk.RSAKey
|
||||||
import com.nimbusds.jose.jwk.source.ImmutableJWKSet
|
import com.nimbusds.jose.jwk.source.ImmutableJWKSet
|
||||||
@ -8,18 +9,17 @@ import com.nimbusds.jose.proc.SecurityContext
|
|||||||
import org.springframework.context.annotation.Bean
|
import org.springframework.context.annotation.Bean
|
||||||
import org.springframework.context.annotation.Configuration
|
import org.springframework.context.annotation.Configuration
|
||||||
import org.springframework.core.annotation.Order
|
import org.springframework.core.annotation.Order
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
import org.springframework.security.core.userdetails.User
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService
|
import org.springframework.security.core.userdetails.UserDetailsService
|
||||||
import org.springframework.security.oauth2.core.AuthorizationGrantType
|
import org.springframework.security.jackson2.SecurityJackson2Modules
|
||||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod
|
|
||||||
import org.springframework.security.oauth2.jwt.JwtDecoder
|
import org.springframework.security.oauth2.jwt.JwtDecoder
|
||||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository
|
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository
|
||||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient
|
|
||||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository
|
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository
|
||||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration
|
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration
|
||||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer
|
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer
|
||||||
|
import org.springframework.security.oauth2.server.authorization.jackson2.OAuth2AuthorizationServerJackson2Module
|
||||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings
|
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings
|
||||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
@ -51,31 +51,25 @@ class SecurityConfig {
|
|||||||
fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||||
http.csrf { it.disable() }
|
http.csrf { it.disable() }
|
||||||
.authorizeHttpRequests { it.anyRequest().authenticated() }
|
.authorizeHttpRequests { it.anyRequest().authenticated() }
|
||||||
|
|
||||||
return http.build()
|
return http.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun userDetailsService(): UserDetailsService {
|
fun userDetailsService(): UserDetailsService {
|
||||||
return InMemoryUserDetailsManager(
|
return InMemoryUserDetailsManager()
|
||||||
User.withDefaultPasswordEncoder()
|
|
||||||
.username("user")
|
|
||||||
.password("password")
|
|
||||||
.roles("USER")
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun registeredClientRepository(): RegisteredClientRepository {
|
fun registeredClientRepository(operations: JdbcTemplate): RegisteredClientRepository {
|
||||||
val testClient = RegisteredClient.withId(UUID.randomUUID().toString())
|
val clientRepository = JdbcRegisteredClientRepository(operations)
|
||||||
.clientId("test-client")
|
val clientRowMapper = KotlinRegisteredClientRowMapper()
|
||||||
.clientSecret("{noop}secret")
|
val classLoader = JdbcRegisteredClientRepository::class.java.classLoader
|
||||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
|
val objectMapper = jacksonObjectMapper()
|
||||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
objectMapper.registerModules(SecurityJackson2Modules.getModules(classLoader))
|
||||||
.build()
|
objectMapper.registerModule(OAuth2AuthorizationServerJackson2Module())
|
||||||
|
clientRowMapper.setObjectMapper(objectMapper)
|
||||||
return InMemoryRegisteredClientRepository(testClient)
|
clientRepository.setRegisteredClientRowMapper(clientRowMapper)
|
||||||
|
return clientRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: qr-access-auth-server
|
||||||
|
datasource:
|
||||||
|
url: jdbc:postgresql://localhost:5432/qr_access
|
||||||
|
username: qr_access_user
|
||||||
|
password: 123
|
Loading…
Reference in New Issue
Block a user