我正在尝试在我的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")
}
答案 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