【问题标题】:Verifying access token from Google using spring security使用 Spring Security 验证来自 Google 的访问令牌
【发布时间】:2020-01-27 14:37:18
【问题描述】:

我正在尝试通过向我的 spring-boot 后端提供一个我从 Google 获得的访问令牌来验证 API 调用。

根据我对文档的理解,只需声明就足够了

security.oauth2.resource.jwk.key-set-uri=https://www.googleapis.com/oauth2/v3/certs

application.properties 文件中,同时启用资源服务器和网络安全。

令牌正在表单的标题中发送

'Authorization': 'Bearer ya29.ImCQBz5-600zVNsB[...]ka-x5kC[...]hvw-BGf3m5Bck-HF[...]44'

当我尝试进行身份验证时,我收到 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]

我希望使用 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());
    }
}

我希望验证令牌并能够显示信息。

我是否需要编写自己的函数来处理这个问题?

【问题讨论】:

  • 您的问题解决了吗?我有一个类似的问题。我同时使用security.oauth2.resource.jwk.key-set-urispring.security.oauth2.resourceserver.jwt.jwk-set-uri 我遇到的问题是在配置上调用 jwk 的请求正在发送请求并且无法解析数据。 (没有“价值”道具)。
  • 抱歉回复晚了。我能够在这篇博文之后解决它:blog.arnoldgalovics.com/…我最终继续沿着这条路走,但是因为我们正在研究类似于这样的内部解决方案:auth0.com/docs/quickstart/backend/java-spring-security5

标签: java spring-security-oauth2 openid-connect google-authentication


【解决方案1】:

也许你必须实现 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);

    }
}

【讨论】:

  • 不幸的是,这似乎不是问题。
【解决方案2】:

我遇到了同样的问题。 原来需要导入特定的 jwt 依赖,默认的 oauth2 依赖对 key-set-uri 不起作用。

我使用的依赖项:

        'org.springframework.cloud:spring-cloud-starter-security',

        'org.springframework.security:spring-security-oauth2-jose',
        'org.springframework.security:spring-security-oauth2-resource-server',

第二个是最重要的。 现在,您的类路径中将拥有JwtDecoderNimbusJwtDecoderJwkSupport,您可以配置SpringBoot。 这是我的设置:

@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;
  }
}

如果您只需要默认的 JWT 令牌验证,则可以使用默认验证(无需设置自定义验证器)。

希望这会有所帮助!

【讨论】:

  • 谢谢。我最终做了一些与此非常相似的事情。
  • @Hagen 请告诉我们你做了什么
猜你喜欢
  • 2017-08-03
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 2019-07-14
  • 2023-02-03
  • 2023-03-03
  • 2014-10-22
  • 2017-04-29
相关资源
最近更新 更多