无法使用 spring boot 和 kotlin 获取 access_token

问题描述 投票:0回答:0

我需要帮助实施我已经做了几天,但它不起作用,因为当我尝试邮递员时,我得到以下回应:

Postman request CLIENT CREDENTIALS METHOD

我正在使用 Maven,这些是依赖项:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.9</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.viergegroup</groupId>
    <artifactId>switch-prosa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>switch-prosa</name>
    <description>Switch Prosa</description>
    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.6.21</kotlin.version>
    </properties>
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>




    </dependencies>



这些是我实现的类:

package com.viergegroup.switchprosa.websecuritybearer

import com.nimbusds.jose.jwk.JWKSelector
import com.nimbusds.jose.jwk.JWKSet
import com.nimbusds.jose.jwk.RSAKey
import com.nimbusds.jose.jwk.source.JWKSource
import com.nimbusds.jose.proc.SecurityContext
import com.shared.commons.AppSettings
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.Ordered
import org.springframework.core.annotation.Order
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.oauth2.core.AuthorizationGrantType
import org.springframework.security.oauth2.core.ClientAuthenticationMethod
import org.springframework.security.oauth2.core.oidc.OidcScopes
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository
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.config.ClientSettings
import org.springframework.security.oauth2.server.authorization.config.ProviderSettings
import org.springframework.security.web.SecurityFilterChain
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.util.*


@Configuration(proxyBeanMethods = false)
class AuthorizationServerConfig {
    @Autowired
    private lateinit var passwordEncoder: PasswordEncoder
    @Autowired
    private lateinit var customAuthenticationProvider: CustomAuthenticationProvider
    @Autowired
    fun bindAuthenticationProvider(authenticationManagerBuilder: AuthenticationManagerBuilder) {
        authenticationManagerBuilder
            .authenticationProvider(customAuthenticationProvider);
    }
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    fun authServerSecurityFilterChain(http: HttpSecurity): SecurityFilterChain? {
        OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http)
       // return http.formLogin(Customizer.withDefaults()).build()
        return http.build()

    }

    @Bean
    fun registeredClientRepository(): RegisteredClientRepository {
        var clientSecret =AppSettings.getInstance().oauthClientSecret

        if(AppSettings.getInstance().encryptClientSecret)
            clientSecret = passwordEncoder.encode(clientSecret)

        println("clientSecret: $clientSecret")
        val client= ClientSettings.builder().requireAuthorizationConsent(true).build()
        val registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId(AppSettings.getInstance().oauthApiClientId)
            .clientSecret(clientSecret)
            .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .authorizationGrantType(AuthorizationGrantType.PASSWORD)
            .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
            .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
            .redirectUri(AppSettings.getInstance().oauthPrimaryRedirectUri)
            .redirectUri(AppSettings.getInstance().oauthSecondaryRedirectUri)
            .scope(OidcScopes.OPENID)
            .scope(AppSettings.getInstance().oauthScope)
            .clientSettings(client)
            .build()
        return InMemoryRegisteredClientRepository(registeredClient)
    }

    @Bean
    fun jwkSource(): JWKSource<SecurityContext?> {
        val rsaKey: RSAKey = generateRsa()
        val jwkSet: JWKSet = JWKSet(rsaKey)
        return JWKSource<SecurityContext?> { jwkSelector: JWKSelector, securityContext: SecurityContext? ->
            jwkSelector.select(
                jwkSet
            )
        }
    }

    private fun generateRsa(): RSAKey {
        val keyPair: KeyPair = generateRsaKey()
        val publicKey: RSAPublicKey = keyPair.public as RSAPublicKey
        val privateKey: RSAPrivateKey = keyPair.private as RSAPrivateKey
        return RSAKey.Builder(publicKey)
            .privateKey(privateKey)
            .keyID(UUID.randomUUID().toString())
            .build()
    }
    private fun generateRsaKey(): KeyPair {
        val keyPair: KeyPair = try {
            val keyPairGenerator: KeyPairGenerator = KeyPairGenerator.getInstance("RSA")
            keyPairGenerator.initialize(2048)
            keyPairGenerator.generateKeyPair()
        } catch (ex: java.lang.Exception) {
            throw IllegalStateException(ex)
        }
        return keyPair
    }


    @Bean
    fun providerSettings(): ProviderSettings? {
        return ProviderSettings.builder()
            .issuer(AppSettings.getInstance().oauthSecondaryRedirectUri)
            .build()
    }


}
package com.viergegroup.switchprosa.websecuritybearer

import com.shared.commons.AppSettings
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.http.HttpMethod
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.web.SecurityFilterChain



@EnableWebSecurity
class DefaultSecurityConfig {
    @Autowired
    private lateinit var customAuthenticationProvider: CustomAuthenticationProvider

    @Bean
    @Throws(Exception::class)
    fun defaultSecurityFilterChain(http: HttpSecurity): SecurityFilterChain? {
        http
            .authorizeRequests()
            .antMatchers(HttpMethod.POST,*(AppSettings.getInstance().disabledOauthUris.toTypedArray())).permitAll()
            .anyRequest().authenticated()
        http
            .formLogin(Customizer.withDefaults())
        return http.build()
    }

    @Autowired
    fun bindAuthenticationProvider(authenticationManagerBuilder: AuthenticationManagerBuilder) {
        authenticationManagerBuilder
            .authenticationProvider(customAuthenticationProvider);
    }
}

和:

package com.viergegroup.switchprosa.websecuritybearer

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;



@Service
class CustomAuthenticationProvider: AuthenticationProvider {
    @Autowired
    private lateinit var  userService: UserService

    @Autowired
    private lateinit var  passwordEncoder: PasswordEncoder

    @Throws(AuthenticationException::class)
    override fun authenticate(authentication: Authentication): Authentication? {
        val username: String = authentication.getName()
        val password: String = authentication.getCredentials().toString()
        val user: UserDetails? = userService.loadUserByUsername(username)
        if(user==null) throw Exception("AuthenticationException")
        return checkPassword(user, password)
    }

    fun checkPassword(user: UserDetails, rawPassword: String): Authentication {
        return if (passwordEncoder.matches(rawPassword, user.password)) {
            UsernamePasswordAuthenticationToken(
                user.username,
                user.password,
                user.authorities
            )
        } else {
            throw BadCredentialsException("Bad Credentials")
        }
    }

    override fun supports(authentication: Class<*>?): Boolean {
        return UsernamePasswordAuthenticationToken::class.java.isAssignableFrom(authentication)
    }


}

如果您知道如何修复它,我将不胜感激。 谢谢

我希望有人能给我一些想法来解决我的问题

spring-boot kotlin oauth-2.0 client credentials
© www.soinside.com 2019 - 2024. All rights reserved.