需要帮助在使用Spring OAuth2的Spring boot 2.1.6.RELEASE
项目中使用Login with Linkedin
。Java版本是11
谷歌和Github非常简单,在同一个项目中工作。我在SpringSocial中尝试了几个示例代码,但由于Spring启动版本不同,它们都失败了。
下面的application.properties不起作用(也尝试过client-authentication-method=post
(,并且在从linkedin检索到授权码后被重定向回(授权码是有效的,我可以用它从Postman获得访问令牌(。
spring.security.oauth2.client.registration.linkedin.provider=linkedin
spring.security.oauth2.client.registration.linkedin.client-name=Linkedin
spring.security.oauth2.client.registration.linkedin.client-id=******
spring.security.oauth2.client.registration.linkedin.client-secret=******
spring.security.oauth2.client.registration.linkedin.redirect-uri=*****
spring.security.oauth2.client.registration.linkedin.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.linkedin.client-authentication-method=form
spring.security.oauth2.client.registration.linkedin.scope=r_emailaddress,r_liteprofile
spring.security.oauth2.client.provider.linkedin.authorization-uri=https://www.linkedin.com/oauth/v2/authorization
spring.security.oauth2.client.provider.linkedin.token-uri=https://www.linkedin.com/oauth/v2/accessToken
spring.security.oauth2.client.provider.linkedin.user-info-uri=https://api.linkedin.com/v2/me
spring.security.oauth2.client.provider.linkedin.user-info-authentication-method=post
SecurityConfig类(也在没有antMatchers
的情况下尝试(:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("*linkedin*").permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.oauth2Login();
}
没有错误,在code
查询参数与state
一起返回到Spring后,它将被重定向回Spring登录。
感谢
我的工作配置:
spring:
security:
oauth2:
client:
registration:
linkedin:
client-id: ????
client-secret: ????
scope: r_liteprofile, r_emailaddress
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
client-name: LinkedIn
client-authentication-method: post
provider:
linkedin:
authorization-uri: https://www.linkedin.com/oauth/v2/authorization
token-uri: https://www.linkedin.com/uas/oauth2/accessToken
user-info-uri: https://api.linkedin.com/v2/me
jwk-set-uri:
user-name-attribute: id
最新春季:org.springframework.security:spring-security-oauth2-client:5.2.2.RELEASE
问题/原因是缺少tokenType。
要复制,请在此位置在org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter
设置断点:
catch (AuthenticationException failed) {
// Authentication failed
unsuccessfulAuthentication(request, response, failed);
return;
}
然后您将看到failed
=此异常:
org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: Error while extracting response for type [class org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse] and content type [application/json]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: An error occurred reading the OAuth 2.0 Access Token Response: tokenType cannot be null; nested exception is java.lang.IllegalArgumentException: tokenType cannot be null
一个";解决方案";这是为了添加一个转换器来添加tokenType。看看https://github.com/spring-projects/spring-security/issues/5983#issuecomment-430620308,并将该调用CCD_ 11加上CCD_https://github.com/jzheaux/messaging-app/blob/master/client-app/src/main/java/sample/config/SecurityConfig.java#L71(加上这节课https://github.com/jzheaux/messaging-app/blob/master/client-app/src/main/java/sample/web/CustomAccessTokenResponseConverter.java。
为了完整起见:这是我在application.properties:中的配置片段
spring.security.oauth2.client.registration.linkedin.client-id: ????
spring.security.oauth2.client.registration.linkedin.client-secret: ????
spring.security.oauth2.client.registration.linkedin.scope=r_emailaddress,r_liteprofile
spring.security.oauth2.client.registration.linkedin.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.linkedin.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.registration.linkedin.client-name = LinkedIn
spring.security.oauth2.client.registration.linkedin.provider=linkedin
spring.security.oauth2.client.registration.linkedin.client-authentication-method = post
spring.security.oauth2.client.provider.linkedin.authorization-uri=https://www.linkedin.com/oauth/v2/authorization
spring.security.oauth2.client.provider.linkedin.token-uri=https://www.linkedin.com/oauth/v2/accessToken
spring.security.oauth2.client.provider.linkedin.user-info-uri=https://api.linkedin.com/v2/me
spring.security.oauth2.client.provider.linkedin.jwk-set-uri =
spring.security.oauth2.client.provider.linkedin.user-name-attribute = id
spring.security.oauth2.client.provider.linkedin.user-info-authentication-method=post
这个问题可以通过WebClientReactiveAuthorizationCodeTokenResponseClient
bean自定义轻松解决——您需要修改响应并在那里添加"token_type: "Bearer"
字段。这可以使用ExchangeFilterFunction来实现。
因此,这里有一个例子,让我们创建一个简单的DTO:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class)
data class Oauth2TokenResponseDTO(
val accessToken: String,
val expiresIn: Int,
val tokenType: String = OAuth2AccessToken.TokenType.BEARER.value
)
然后,在您的反应式安全配置中只需添加下一个:
private fun modifyResponse(): ExchangeFilterFunction {
return ExchangeFilterFunction.ofResponseProcessor { response: ClientResponse ->
response.bodyToMono(Oauth2TokenResponseDTO::class.java)
.map { objectMapper.writeValueAsString(it) }
.map { ClientResponse.from(response).body(it).build() }
}
}
最后一个:
@Bean
fun webClientReactiveAuthorizationCodeTokenResponseClient(): WebClientReactiveAuthorizationCodeTokenResponseClient {
val tokenResponseClient = WebClientReactiveAuthorizationCodeTokenResponseClient()
val webClient = WebClient.builder()
.clientConnector(ReactorClientHttpConnector(HttpClient.create().wiretap(true)))
.filter(modifyResponse())
.build()
tokenResponseClient.setWebClient(webClient)
return tokenResponseClient
}
附言:请注意,如果您有另一个oauth2提供者,则需要在ExchangeFilterFunction
中实现一个filter方法。