简体   繁体   English

使用 spring 安全性验证来自 Google 的访问令牌

[英]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.现在,您的类路径中将拥有JwtDecoderNimbusJwtDecoderJwkSupport ,您可以配置 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM