[英]Verifying access token from Google using spring security
I'm trying to authenticate API-calls with my spring-boot backend by giving it an access token that I've gotten from Google.我正在尝试使用我的 spring-boot 后端验证 API 调用,方法是为其提供我从 Google 获得的访问令牌。
From what I understand of the documentation it should be enough to just declare根据我对文档的理解,只需声明就足够了
security.oauth2.resource.jwk.key-set-uri=https://www.googleapis.com/oauth2/v3/certs
in the application.properties
file along with enabling resource server and web security.在application.properties
文件中,同时启用资源服务器和 web 安全性。
The token is being sent in in the header on the form令牌正在表格上的 header 中发送
'Authorization': 'Bearer ya29.ImCQBz5-600zVNsB[...]ka-x5kC[...]hvw-BGf3m5Bck-HF[...]44'
When I try to authenticate I get a 401 Unauthorized error with the following console error:当我尝试进行身份验证时,我收到 401 Unauthorized 错误,并出现以下控制台错误:
OAuth2AuthenticationProcessingFilter: Authentication request failed: error="invalid_token", error_description="An I/O error occurred while reading the JWT: Invalid UTF-8 start byte 0xad at [Source: (byte[])"??"; line: 1, column: 3]
I'm hoping to use most of what I can of the spring security libraries, but I've tried to write my own simple beans for token management.我希望使用 spring 安全库的大部分功能,但我尝试编写自己的简单 bean 来进行令牌管理。
@Configuration
@EnableResourceServer
@EnableWebSecurity
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER");
}
@Bean
public TokenStore tokenStore() {
return new jwkTokenStore("https://www.googleapis.com/oauth2/v3/certs");
}
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
return defaultTokenServices;
}
@Override
public void configure(ResourceServerSecurityConfigurer config) {
config.tokenServices(tokenServices());
}
}
I expect to authenticate the token and be able to display information.我希望验证令牌并能够显示信息。
Do I need to write my own functions to handle this?我是否需要编写自己的函数来处理这个问题?
Maybe you must implement the WebSecurityConfigurerAdapter也许你必须实现 WebSecurityConfigurerAdapter
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class RestSecurityConfig extends WebSecurityConfigurerAdapter {
private final AADAppRoleStatelessAuthenticationFilter appRoleAuthFilter;
private final RestAuthenticationEntryPoint unauthorizedHandler;
private final RestAccessDeniedHandler accessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.antMatchers("/actuator/refresh").hasRole("Admin")
.antMatchers("/actuator/health").permitAll()
.anyRequest().fullyAuthenticated();
http.addFilterBefore(appRoleAuthFilter, UsernamePasswordAuthenticationFilter.class);
http.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler)
.authenticationEntryPoint(unauthorizedHandler);
}
}
I had the same problem.我有同样的问题。 It turns out that you need to import specific jwt dependencies, the default oauth2 dependencies will not work with key-set-uri.事实证明,您需要导入特定的 jwt 依赖项,默认的 oauth2 依赖项不适用于 key-set-uri。
My dependecies that I use:我使用的依赖项:
'org.springframework.cloud:spring-cloud-starter-security',
'org.springframework.security:spring-security-oauth2-jose',
'org.springframework.security:spring-security-oauth2-resource-server',
The second one is the most important.第二个是最重要的。 Now, you will have the JwtDecoder
and NimbusJwtDecoderJwkSupport
on your classpath you can configure SpringBoot.现在,您的类路径中将拥有JwtDecoder
和NimbusJwtDecoderJwkSupport
,您可以配置 SpringBoot。 This is my setup:这是我的设置:
@NoArgsConstructor
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
class WebAppConfig extends WebSecurityConfigurerAdapter {
@Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}")
private String issuer;
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
private String jwkSetUri;
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
...
.and()
.oauth2ResourceServer()
.jwt()
.decoder(decoder());
}
private JwtDecoder decoder() {
List<OAuth2TokenValidator<Jwt>> validators = new ArrayList<>();
validators.add(new JwtTimestampValidator());
validators.add(new JwtIssuerValidator(issuer));
validators.add(new TokenSupplierValidator(List.of(StringUtils.split(androidClientId,","))));
NimbusJwtDecoderJwkSupport decoder = new NimbusJwtDecoderJwkSupport(jwkSetUri)
decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(validators));
return decoder;
}
}
If you need only default JWT token validation, you can go with the default validation (no need for setting up the custom validator).如果您只需要默认的 JWT 令牌验证,则可以使用默认验证 go(无需设置自定义验证器)。
Hope this helps!希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.