不含用户名密码和UserDetailsService接口的@PreAuthorize。

问题描述 投票:0回答:1

所以,这里的情况是这样的。

我有一个登录API,它返回jwt token给客户端,这个API有注解 @PermitAll.

然后,我有另一个API是安全的,只有在验证jwt token后才能访问。向安全的API发送请求的方式是这样的 Authorization 参数在头中加入jwt token的值,然后将请求传递给安全API。请注意 authorization type 这个API的是 No Auth. 我写了一个类 JwtRequestFilter extends OncePerRequestFilter在其中,我拦截了请求,提取了令牌,验证了令牌,返回了相应的响应,一切都很顺利。但是有一个问题,这个问题就是有 @PreAuthorize("hasAuthority('RANDOM_PRIV_1')") 注解在控制器类中方法的顶部,并且它没有被控制器类中的 JwtRequestFilter 而且实际上它不应该这样做,因为这不是它的工作。

我知道 list of GrantedAuthorities 传递给执行的 UserDetailsService 并通过方法进行验证 loadUserByUsername. 但我不能使用这个接口的实现,原因是,它的实现只有在当 authorization typeBasic Auth 而我没有使用这种类型的认证。

因此,我正在寻找一个接口类,我可以通过它来验证 GrantedAuthorities的方式来验证。UserDetailsService.

如果没有这样的功能,那么我有第二种工作方案,扩展了 HandlerInterceptorAdapter 并在 preHandle我验证了token,也验证了与用户相关联的授予权限,并验证了(manually) 方法上的PreAuthorize注解。这对我来说是有效的,但我仍然在寻找更干净的解决方案。

P.S: 我也看了这个链接,但没有找到任何有用的信息。没有UserDetailsService方法的Spring引导基本认证。.

任何帮助将是非常感激的。

spring-boot spring-security jwt authority
1个回答
0
投票

如果你想使用jwt来验证请求,那么你可以使用Spring Security对它的内置支持。

你仍然需要自己创建jwt,但是对于处理jwt并将其转化为Granted Authorities,你可以这样做。

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

这告诉Spring Security要建立一个过滤器(BearerTokenAuthenticationFilter)来提取token并进行处理,可能和你的 JwtRequestFilter.

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

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

最后,关于你提出的授权问题: 例如,假设您提到的授权(RANDOM_PRIV_1)在你的JWT中被列为作用域,你可以构造一个 JwtAuthenticationConverter 豆。

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())
        )
    );

然后,当请求中出现一个JWT时,Spring Security会对其进行处理,提取权限,并验证它们是否与使用JWT的权限相匹配。@PreAuthorize 注释。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.