是否缓存了“预授权”注释?

时间:2019-02-21 19:01:08

标签: java spring spring-boot spring-security

在Spring Boot中,是否按请求缓存@PreAuthorize("@bean.checkAuthorization(#argument)")个调用?

作为一个最小的示例,假设@Controller具有以下REST端点:

@GetMapping("/api/test") public String testAuthorization() {
    String argument;

    String foo = service.foo(argument);
    String bar = service.bar(argument); // same arguments
    return bar + foo;
}

以及foo中的barservice方法的定义如下:

@PreAuthorize("@bean.checkAuthorization(#argument)")
public String foo(String argument) {
    return "hello";
}


@PreAuthorize("@bean.checkAuthorization(#argument)")
public String bar(String argument) {
    return "world";
}

用例。鉴于Bean.checkAuthorization(argument)是一个运行成本很高的函数( eg 它会进行数据库调用),但它是无状态的( ie 对于给定参数的结果不会因多次调用而改变),每个请求仅需进行一次调用。因此,是否可以为整个请求缓存结果,但确保对每个请求都执行检查? (没有长期缓存)

2 个答案:

答案 0 :(得分:1)

不是 是个好主意。

在实现这种方法时,您很容易受到缓存中毒攻击;也就是说,您将面临任何未经数据库调用授权的人所面临的威胁,而这种威胁就是您不希望他们获得的方式。

在确定是否应允许用户访问受保护资源而不是使该资源泄漏方面,对性能造成轻微影响是可取的

更好的选择可能是调查造成数据库调用如此昂贵的原因,或者说服企业这是保护该资源所需要支付的费用。

答案 1 :(得分:0)

只需启用缓存:@EnableCaching,然后将@Cacheable("checkauth")放在checkAuthorization方法的顶部即可。

编辑我意识到我的回答不符合要求,如下面的评论所述。肯定有一些特别的方法可以做到这一点,例如:Caching per request with Spring使用AOP

但是太复杂了!我想像一下,对于大多数具有保留策略@Cached(expire = 1, timeUnit = TimeUnit.MINUTES)的现代Web应用程序,大多数请求都将花费一秒钟的时间,而预先优化是魔鬼。

但是对于这种标准问题,我发现这种方法真的是非标准的。相反,我建议您使用以下角色:FOOBAR,这将使您可以简单地使用以下方法来注释方法:hasRole('FOO')hasRole('BAR')

@Service
public class MyUserDetailsService implements UserDetailsService {
 
    @Autowired
    private UserRepository userRepository;
 
    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username);

        if (checkAuthorizationFoo(user)) user.addRole("FOO");
        if (checkAuthorizationBar(user)) user.addRole("BAR");

        return new user;
    }
}

@PreAuthorize("hasRole('FOO')")
public String foo(String argument) {

@PreAuthorize("hasRole('BAR')")
public String bar(String argument) {

请注意,尽管这并不是很懒,并且您的checkAuthorization方法总是被调用,但这是这种方法的缺点。您可以花点时间使它变得懒惰,但是再次注意要进行多少优化。