Spring OAuth2密码流不断失败

时间:2018-04-10 22:29:33

标签: spring-boot spring-security oauth-2.0 kotlin spring-security-oauth2

我正在尝试在我的Spring Boot应用程序中启用OAuth2密码流,但是,无论我尝试什么,我都无法让它运行。

以下是我的配置。 对于TokenStore我配置了JdbcTokenStore bean,而UserDetailsService只是从我的自定义用户表中加载用户。 我还添加了属性security.oauth2.resource.filter-order=3

对于Spring Boot,我正在使用2.0.0.RELEASE和Spring Security 2.3.0.RELEASE

授权服务器和资源服务器都在一个应用程序中。

以下POST(使用SoapUI)一直失败:

http://localhost:8080/oauth/token?grant_type=password&username=hans.wurst&password=bla&client_id=androidAppClient

我收到了消息

  

拒绝访问(用户是匿名的);

Debug告诉我应用了以下过滤器:

Security filter chain: [
  WebAsyncManagerIntegrationFilter
  SecurityContextPersistenceFilter
  HeaderWriterFilter
  LogoutFilter
  BasicAuthenticationFilter
  RequestCacheAwareFilter
  SecurityContextHolderAwareRequestFilter
  AnonymousAuthenticationFilter
  SessionManagementFilter
  ExceptionTranslationFilter
  FilterSecurityInterceptor
]

授权服务器:

@Configuration
@EnableAuthorizationServer
class AuthorizationServerConfiguration : AuthorizationServerConfigurerAdapter() {

    @Autowired
    private lateinit var dataSource: DataSource

    @Autowired
    private lateinit var tokenStore: TokenStore

    @Autowired
    @Qualifier("authenticationManagerBean")
    private lateinit var authenticationManager: AuthenticationManager

    override fun configure(clients: ClientDetailsServiceConfigurer) {
        clients.jdbc(dataSource)
    }

    override fun configure(endpoints: AuthorizationServerEndpointsConfigurer) {
        endpoints
                .authenticationManager(authenticationManager)
                .tokenStore(tokenStore)
    }

}

网络安全:

@Configuration
class WebSecurityConfiguration : WebSecurityConfigurerAdapter() {

    @Autowired
    @Qualifier(USER_DETAILS_SERVICE)
    private lateinit var userDetailsService: UserDetailsService

    @Bean
    @Throws(Exception::class)
    override fun authenticationManagerBean(): AuthenticationManager = super.authenticationManagerBean()

    @Throws(Exception::class)
    override fun configure(web: WebSecurity) {
        web.debug(true)
    }

    override fun configure(auth: AuthenticationManagerBuilder) {
        auth.userDetailsService(userDetailsService)
    }

    override fun configure(http: HttpSecurity) {
        http
                .authorizeRequests()
                .anyRequest()
                .authenticated()
    }
}

资源服务器:

@Configuration
@EnableResourceServer
class ResourceServerConfiguration : ResourceServerConfigurerAdapter() {

    override fun configure(http: HttpSecurity) {
        http
                .authorizeRequests()
                .antMatchers("/registration", "/customer/check")
                .anonymous()
                .anyRequest()
                .authenticated()
    }

}

用户详细信息服务:

const val USER_DETAILS_SERVICE = "userDetailsService";

@Transactional
@Service(USER_DETAILS_SERVICE)
class CustomerUserDetailsService @Autowired constructor(private val customerRepository: CustomerRepository) : UserDetailsService {

    @Throws(UsernameNotFoundException::class)
    override fun loadUserByUsername(username: String): UserDetails =
            customerRepository
                    .findCustomerCredentialsByUserName(username)
                    ?.let { User(it.userName, it.password, emptyList()) }
                    ?: throw UsernameNotFoundException("Could not find customer with username $username")
}

1 个答案:

答案 0 :(得分:0)

客户androidAppClient似乎没有password中设置的authorized_grant_types授权类型。

检查DB(oauth_client_details)中的客户端详细信息表,确保为此客户端设置了password grant type。 如果与其他授权类型一起设置,请确保授权类型中没有空格,例如,('password,refresh_token')

/oauth/token端点的发布请求需要Base64“clientId:clientSecret”格式的客户端凭据。

curl --request POST \
  --url http://localhost:8443/auth-service/oauth/token \
  --header 'authorization: Basic UkVXQVJEU19QT1QUxfQURNSU46cGFzc3dvcmQ=' \
  --header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
  --form username=testuser \
  --form password=password \
  --form grant_type=password