在Spring服务中跳过对内部服务进行服务调用的授权

时间:2018-11-25 23:14:46

标签: java spring spring-security

我正在使用Spring分层体系结构,对服务类中的请求执行授权。一种服务可能如下所示:

@Service
public class SomeService {

    public void findOne(Long id) {
        assertPrivilege("READ");
        // ...
    }
}

现在,assertPrivilege()使用SecurityContextHolder获得GratedAuthority对象的列表。将授权逻辑放入服务中,控制器不必担心这一点-甚至在从一个控制器调用多个服务时也是如此。

问题在于,除非获得授权,否则所有其他服务现在都无法访问该方法。但是,有些线程(例如调度程序)在某个时刻完全调用该方法而没有准备好Authentication对象。在某些情况下,如果它是同一线程,则SecurityContext也将返回当前身份验证。

现在,如何重构此逻辑以实现其他内部线程在未经授权的情况下调用该方法。是否需要进行设计更改,是否可能需要第二个包装器类,例如SomeService(无授权)和SomeClientService(具有授权)?另一种可能性是直接访问存储库。

2 个答案:

答案 0 :(得分:1)

最好使用@PreAuthorize("hasRole('ROLE_VIEWER') or hasRole('ROLE_EDITOR') or #id == authentication.principal.username")代替方法see tutorial, there are many of them

通常,您的业务逻辑不应与安全框架混合使用-这就是为什么有@PreAuthorize@PostAuthorize的原因-开发人员应该能够独立于业务逻辑定义用户访问权限-这是两个不同的要求。

没有一种简单的方法可以为一个用户(内部呼叫,外部应用程序等)禁用Spring Security,也不推荐(错误等),您可以为外部应用程序创建特殊角色或使用Concurrency Support代表用户执行内部呼叫。

答案 1 :(得分:0)

代理服务方法似乎是最简单的方法,因为您无需将授权逻辑移出该层。作为一个方面来管理授权将是该解决方案的关键。否则,您总是可以直接在控制器中管理这些检查,因此每个终结点计算机都会根据其设计使用的客户端类型来处理它。