Spring Boot 2.x中如何实现Servlet的<run-as>标签功能解决EJB权限问题?
Spring Boot 2.x 实现原Servlet 功能的解决方案
方法一:通过ServletRegistrationBean配置Run-As角色
Spring Boot中注册Servlet时,可通过ServletRegistrationBean直接设置run-as角色,完全对应原web.xml中<run-as>标签的功能:
@Configuration public class ServletConfig { @Bean public ServletRegistrationBean<RM2KMUDelegatingServlet> rm2kmuServletRegistration() { ServletRegistrationBean<RM2KMUDelegatingServlet> registration = new ServletRegistrationBean<>(new RM2KMUDelegatingServlet(), "/your-servlet-mapping/*"); // 指定原web.xml中配置的run-as角色 registration.setRunAsRole("keyservice_readonly"); return registration; } }
该方法依赖Servlet 3.0+规范,Spring Boot内嵌的Tomcat、Jetty等容器均支持。配置后,整个RM2KMUDelegatingServlet的执行都会以指定角色身份运行,调用EJB时自动携带该权限。
方法二:手动切换安全上下文(适用于局部EJB调用场景)
如果方法一未生效,或仅需在特定EJB调用时切换身份,可手动替换安全上下文后再调用EJB,执行完成后恢复原上下文:
// 示例:调用KeyOperationsEJB的代码片段 public void retrieveKeyEntry() { // 通过JNDI获取EJB实例 KeyOperationsEJB keyOperationsEjb = lookupEjbFromJndi(); // 保存原安全上下文 SecurityContext originalCtx = SecurityContextHolder.getContext(); try { // 创建携带指定角色的认证信息 Collection<GrantedAuthority> authorities = Collections.singletonList( new SimpleGrantedAuthority("keyservice_readonly") ); UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken("run-as-user", null, authorities); // 设置新的安全上下文 SecurityContext newCtx = SecurityContextHolder.createEmptyContext(); newCtx.setAuthentication(authToken); SecurityContextHolder.setContext(newCtx); // 执行EJB调用 keyOperationsEjb.retrieveEntry(); } finally { // 恢复原上下文,避免影响后续请求 SecurityContextHolder.setContext(originalCtx); } }
关键排查点
- 确认容器(内嵌或外部应用服务器)已启用安全配置,且
keyservice_readonly角色已正确配置并映射 - 检查EJB的
@RolesAllowed注解是否准确指定了keyservice_readonly,无拼写错误 - 若使用外部应用服务器(如WildFly、WebSphere),需确保服务器的EJB安全策略允许run-as身份切换
内容的提问来源于stack exchange,提问作者wlkl
相关产品推荐
相关产品推荐

