Spring OAuth2密码流一直失败
Posted
技术标签:
【中文标题】Spring OAuth2密码流一直失败【英文标题】:Spring OAuth2 Password Flow keeps failing 【发布时间】:2018-09-20 16:06:39 【问题描述】:我正在尝试在我的 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
我收到消息
访问被拒绝(用户是匿名的);
调试告诉我应用了以下过滤器:
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")
【问题讨论】:
您可以尝试在 ResourceServerConfiguration 中添加“/registration”、“/customer/check”之外的“/oauth/token”、“/oauth/authorize”、“/oauth/confirm_access”吗? 【参考方案1】:客户端androidAppClient
似乎没有在authorized_grant_types
中设置password
授权类型。
检查 DB (oauth_client_details
) 中的客户端详细信息表,确保为此客户端设置了 password
授权类型。 如果它与其他授权类型一起设置,请确保授权类型中没有空格,例如 ('password,refresh_token')
.
/oauth/token
端点的 post 请求需要 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
【讨论】:
oauth_client_details 中的客户端很好。对 client_id:client_secret 使用基本身份验证有效,并且我的请求已通过身份验证。但是,在那之后我收到了 404 响应,即使在日志中我可以看到 /oauth/token 已映射到TokenEndpoint.postAccessToken
。
哦,好吧,我想通了。我在 Spring 中使用 JAX-RS 资源。这会以某种方式干扰 OAuth2 端点以上是关于Spring OAuth2密码流一直失败的主要内容,如果未能解决你的问题,请参考以下文章
针对授权标头的Spring Security OAuth2 CORS问题
Google OAuth2.0 是不是支持资源所有者密码凭据流的 OAuth 流?
在 Spring Cloud Gateway 的 oauth2 客户端流中禁用重定向到 oauth2/authorization/registrationId
让 oauth2 与 spring-boot 和 rest 一起工作