如何使用 spring 安全性在特定端点上启用 OAuth

How to enable OAuth on a specific endpoint using spring security

我正在尝试熟悉 Spring 安全性,特别是从 Spring 安全性 OAuth 迁移到 Soring 安全性(如下面的 example/guide https://github.com/spring-projects/spring-security/wiki/OAuth-2.0-Migration-Guide)。

但是,我似乎只收到 403 Forbidden 错误。我正在从 Postman 访问并使用我公司现有的 OAuth 服务器。我能够从授权服务器获取令牌,所以我知道我的凭据是正确的,并且我已经验证了 OAuth 用户拥有的角色。

我正在使用以下依赖项:

implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-web'

这是我尝试访问的简单端点:

@RestController
public class AppController
{
   @GetMapping("/hello")
    public String hello()
    {
        return "hello";
    }
}

这是我的 application.yml 文件:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: <<company-website-here>>/uaa/oauth/token_keys

这是我的安全配置 class:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
    @Override
    protected void configure(HttpSecurity http) throws Exception
    {
        http.authorizeRequests()
                .antMatchers(HttpMethod.GET, "/hello").hasRole("MY_ROLE")
                .anyRequest().authenticated()
                .and()
                .oauth2ResourceServer().jwt();
    }
}

我似乎无法弄清楚为什么我似乎只收到 403 错误。我还尝试将 @EnableWebSecurity 添加到安全配置 class,但这并没有什么不同。将 auth 服务器 URL 显式添加到服务器 and/or 手动创建 JwtDecoder 也没有成功; url 似乎是根据其 属性 名称自动从 yml 文件中提取的。

我正在尝试不再使用 org.springframework.security.oauth.boot 依赖项和 ResourceServerConfigurerAdapter。

我必须像这样添加自己的转换器:

private static class JwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken>
    {
        private final Converter<Jwt, Collection<GrantedAuthority>> jwtGrantedAuthoritiesConverter;

        public JwtAuthenticationConverter()
        {
            this.jwtGrantedAuthoritiesConverter = jwt -> jwt
                    .getClaimAsStringList("authorities")
                    .stream()
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toList());
        }

        @Override
        public final AbstractAuthenticationToken convert(@NonNull Jwt jwt)
        {
            Collection<GrantedAuthority> authorities = jwtGrantedAuthoritiesConverter.convert(jwt);
            return new JwtAuthenticationToken(jwt, authorities, jwt.getClaimAsString("client_id"));
        }
    }

然后必须将其添加到主要安全配置中:

.jwtAuthenticationConverter(new JwtAuthenticationConverter());

可能会发生一些事情。

  1. 在迁移到 Spring Security 5 时,您可能需要手动提取权限。检查这个 .

  2. 您正在使用 hasRole 函数,这将在您的 authority/role 之前附加“ROLE_”。所以如果你的 JWT 令牌上的角色不是 ROLE_JWT_ROLE 你应该使用 有交易.