4

我有一个带有 Spring MVC 3.2 和 Spring Security 3.1 的 Web 应用程序

我正在使用基于角色的安全性,并且已经实现了 UserDetailsS​​ervice 和 UserDetails 来提供 GrantedAuthority。

我已经使用 jsr250-annotations 启用了全局方法安全性

到目前为止,一切都按预期工作,登录的用户方法访问权限仅限于声明的角色。

我有一个进一步的要求,即作为具有“系统角色”的特殊用户运行在应用程序初始化期间调用的某些方法,理想情况下是按照 JavaEE RunAs 的方式运行。我不确定如何在 Spring Security 中执行此操作。

我是否应该尝试创建一个PreAuthenticatedAuthenticationToken具有一些组成的价值观和“系统角色”权限的人。
然后我可以SecurityContextHolder.getContext().setAuthentication(token); 在初始化应用程序时执行类似的操作。

或者我应该尝试使用 RunAsManager。这听起来像是我需要的,但我还没有找到任何简单的例子来说明我如何实际使用它。

我对 Spring Security 还很陌生,我不确定最好的方法。

4

3 回答 3

4

当我的应用程序启动时

  • 我在我的 spring bean 中运行一个 post 构造方法,以在内存中创建一个具有系统角色的特殊用户。
  • 这个用户对象实现了
    org.springframework.security.core.userdetails.UserDetails
    界面。
  • 然后我使用用户创建一个安全令牌
    org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
  • 然后在安全上下文中设置令牌。

    @Service
    @Transactional(readOnly = true)
    public class ApplicationConfiguration{
        @Inject
        MyService myService;
        @PostConstruct
        @Transactional(readOnly = false)
        public void init(){
    
            // ######## Application Starting #######"
    
            // Create a user that meets the contract of the Spring UserDetails interface
    
            UserAccountImpl sysAcc = new UserAccountImpl("system", "system", "system");
            UserRole role = new UserRole(Role.SYSTEM_ROLE);
            role.addUserPermission(Permission.SYSTEM);
            sysAcc.addUserRole(role);
            UserDetailsAdapter userDetails = new UserDetailsAdapter(sysAcc);
    
            // Create a token and set the security context
    
            PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken( userDetails, userDetails.getPassword(), userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(token);
    
            // Now call service method with roles allowed  
    
            myService.initialiseSystem();
        }
    }
    

    ……

    public interface MyService {
        @RolesAllowed(SYSTEM)
        public void initialiseSystem();
    }
    
于 2013-09-25T14:53:02.747 回答
3

您真的需要在上述应用程序初始化中附加一个角色吗?为什么不直接提取需要在初始化期间运行的代码,如下所示:

public interface Service {

    @Secured("hasRole('USER')")
    void service();
}

public class DefaultService implements Service {

    @Override
    public void service() {
        doService();
    }

    public void doService() {
        // Implementation here
    }
}

...

public class AppInitializer {

    @Autowired
    private DefaultService service;

    public void init() {
        service.doService();
    }
}
于 2013-09-19T19:14:03.927 回答
1

我相信在这种情况下,对您来说一个好的解决方案是使用 Spring Security OAuth,因为它允许您更好地集成到自定义规则以通过令牌进行访问。

http://projects.spring.io/spring-security-oauth/

于 2013-09-25T14:34:25.187 回答