0

所以这里是场景。

我有登录 API,它将 jwt 令牌返回给客户端,这个 API 有注释@PermitAll

然后我有另一个受保护的 API,只能在验证 jwt 令牌后访问。对安全 API 的请求是以这样一种方式发送的,即Authorization在标头中添加带有 jwt 令牌值的参数,并将请求传递给安全 API。请注意,authorization type此 API 是No Auth. 我写了一个类JwtRequestFilter extends OncePerRequestFilter,我在其中拦截了请求,提取了令牌,验证了它,返回了适当的响应,一切都很好。但是有一个问题,问题是@PreAuthorize("hasAuthority('RANDOM_PRIV_1')")控制器类中方法的顶部有注释,它没有被验证,JwtRequestFilter实际上不应该,因为这不是它的工作。

我知道list of GrantedAuthorities被传递给实现UserDetailsService并通过方法得到验证loadUserByUsername。但是我不能使用这个接口的实现,原因是,它的实现只有在 is 时才被调用,authorization typeBasic Auth我没有使用这种类型的身份验证。

所以我正在寻找的是一个我可以验证的接口/类GrantedAuthorities;它的验证方式由UserDetailsService.

如果没有这样的功能,那么我有第二个扩展工作选项,HandlerInterceptorAdapter在 中preHandle,我验证令牌以及验证与用户关联(manually)的grantedAuthorities,并根据方法上存在的 PreAuthorize 注释验证它们。这对我有用,但我仍在寻找更清洁的解决方案。

PS:我也浏览了这个链接,但没有找到任何有用的信息。 没有 UserDetailsS​​ervice 方法的 Spring Boot 基本身份验证

任何帮助将非常感激。

4

1 回答 1

0

如果您想使用 JWT 对请求进行身份验证,则可以使用 Spring Security 的内置支持。

您仍然需要自己创建 JWT,但要处理 JWT 并将其转换为授权权限,您可以执行以下操作:

http
    .authorizeRequests(...
    .oauth2ResourceServer(oauth2 -> oauth2
        .jwt(jwt -> {})
    );

这告诉 Spring Security 建立一个过滤器 ( BearerTokenAuthenticationFilter) 来提取令牌并处理它,可能很像你的JwtRequestFilter.

由于您是在本地创建 JWT(例如,而不是使用授权服务器),因此您需要告诉 Spring Security 如何验证令牌。这通常使用对称密钥完成:

@Bean
JwtDecoder jwtDecoder() {
    return NimbusJwtDecoder.withSecretKey(...).build();
}

最后,关于授予权限的问题。例如,假设您提到的权限 ( RANDOM_PRIV_1) 在您的 JWT 中列为范围,您可以构造一个JwtAuthenticationConverterbean:

JwtAuthenticationConverter jwtAuthenticationConverter() {
    JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
    converter.setJwtGrantedAuthoritiesConverter(jwt -> {
        Collection<String> scopes = jwt.getClaim("scope");
        return scopes.stream()
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    });
    return converter;
}

然后将其添加到 DSL:

http
    .authorizeRequests(...
    .oauth2ResourceServer(oauth2 -> oauth2
        .jwt(jwt -> jwt
            .jwtAuthenticationConverter(jwtAuthenticationConverter())
        )
    );

@PreAuthorize然后,当请求中出现 JWT 时,Spring Security 将处理它,提取权限,并使用注解验证它们是否匹配。

于 2020-06-11T17:51:17.163 回答