我按照 BalusC 代码在 Java EE 6 ( http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html) 中管理用户身份验证,如果我留在同一个 Web 容器中,它会很好用。
我面临一个问题,也许任何人都可以帮助我。
注入(inject)驻留在 Web 容器中的 EJB 时,SecurityUtils.getSubject()
从该 EJB 的任何方法都可以正常工作。
问题是当我尝试在来自另一个容器(甚至是同一 EAR 中的 ejb jar)的注入(inject) EJB 上执行此操作时。
我得到的错误是:用例是:Caused by: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton. This is an invalid application configuration.
托管 bean A
,注入(inject)了无状态 session bean B
。 A
类驻留在 myApp.war 中,B
类驻留在 myApp.ejb 中,两者都在 myApp.ear 中。我正在从 B
类调用 SecurityUtils
。
你有解决这个问题的线索吗?
我正在运行 JSF 2、Java EE 6、JBoss 7.1。
最佳答案
我自己在回答这个问题。
我使用 Filter 和 JBoss 的自定义 LoginModule 解决了集成问题:
过滤器(必须在shiro过滤器调用后应用):
public class ShiroJAASIntegrationFilter implements Filter{
static Logger logger = Logger.getLogger(ShiroJAASIntegrationFilter.class);
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)arg0;
Principal userPrincipal = httpServletRequest.getUserPrincipal();
HttpSession session = httpServletRequest.getSession(false);
if(userPrincipal!=null){
if(session!= null && session.getAttribute("shiroAuthenticated")==null){
String name = userPrincipal.getName();
try {
httpServletRequest.login(name,"");
session.setAttribute("shiroAuthenticated",true);
} catch (ServletException e) {
logger.debug("Unable to authenticate user" + e.getMessage());
}
}
}
arg2.doFilter(arg0, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
登录模块,它只是将用户设置为经过身份验证:
public class ShiroJAASLoginModule extends UsernamePasswordLoginModule {
/**
* Always return true.
*/
protected boolean validatePassword(String inputPassword,
String expectedPassword) {
return true;
}
protected Group[] getRoleSets() throws LoginException {
//TODO: if needed, add roles
Group[] roleSets = { new SimpleGroup("Roles") };
roleSets[0].addMember(new SimplePrincipal(getUsername()));
return roleSets;
}
@Override
protected String getUsersPassword() throws LoginException {
return null;
}
}
模块必须在standalone.xml中定义:
<security-domain name="shiro" cache-type="default">
<authentication>
<login-module code="web.security.shiroJaasIntegration.ShiroJAASLoginModule" flag="required"/>
</authentication>
</security-domain>
最后,在您的应用程序 jboss-web.xml 中定义安全域:
<jboss-web>
<security-domain>shiro</security-domain>
</jboss-web>
关于jakarta-ee - Java EE 6 应用程序中的 Shiro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18326128/