如何让Linkedin OAuth在Spring Boot中工作



需要帮助在使用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

这个问题可以通过WebClientReactiveAuthorizationCodeTokenResponseClientbean自定义轻松解决——您需要修改响应并在那里添加"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方法。

最新更新