如何将JNDI与WAX一起使用(Websphere Application Server 8.5.5)

时间:2015-04-13 10:43:06

标签: jndi shiro websphere-8

Haven并没有真正使用过Web Sphere Application Server(8.5.5)之前我没有任何关于JNDI的实际经验,而且我甚至只与Shiro合作了几天。 我仍然需要为JNDI获得一个自定义的Shiro-realm,以便应用程序和Shiro共享一个领域的公共实例(以便域可以通过注入访问ejb资源)

到目前为止,我是这样做的:

WEB-INF / shiro.ini

[main]
realmFactory = org.apache.shiro.realm.jndi.JndiRealmFactory
realmFactory.jndiNames = realms/ShiroRealm
...

一个自定义的Shiro-Realm(现在只是嘲笑)

import javax.faces.bean.SessionScoped;
@SessionScoped
public class MockRealm extends AuthorizingRealm implements Serializable {

  @Inject public UserMB user;

  @Override protected AuthenticationInfo doGetAuthenticationInfo(...) ...
  @Override protected AuthorizationInfo doGetAuthorizationInfo(...) ...
}

自定义CredentialsMatcher

public class MockCredentialsMatcher implements CredentialsMatcher {

  @Override public boolean doCredentialsMatch(...) ...
}

我有一个shiro-startup类如下

@Singleton
@Startup
public class ShiroStartup {

  @Inject
  private MockRealm realm;

  @PostConstruct
  public void setup() {
    Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
    InitialContext ic = new InitialContext(env);

    try {
    Object obj = ic.lookup("realms/ShiroRealm"); // This is expected to fail when the application is published
        } catch (NamingException ne) {
            this.realm.setCredentialsMatcher(new MockCredentialsMatcher());
            ic.rebind("realms/ShiroRealm", this.realm);
            System.out.println("Bound: realms/ShiroRealm";
        }
    } catch (NamingException e) {
        e.printStackTrace();
    }
  }
}

我之前发现一篇帖子建议以这种方式桥接注入范围,实际上这是有效的,但只有在GlassFish(v4)上运行此代码时才会这样。 我很确定这也适用于WAS 8.5.5,但无法解决此错误。 (对某人来说可能是微不足道的,但是......)

我得到的错误是抱怨jndi名称&#34; realms / ShiroRealm&#34;未找到/不能使用。 (我稍后会发布确切的Exception,目前在运行服务器时遇到问题) 我还没有找到如何给出这个名字(这开始需要时间,即使我希望这种信息很容易找到),所以我在这里发帖,希望有人能提出建议我

(注意:我在这里只复制了我认为相关的部分。在GlassFish上运行时调试代码时,我会在预期时在所有正确的位置点击)

//更新(为了完整性,虽然我不认为这些与此问题相关)
beans.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<beans
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd">
  <interceptors>
    <class>com.example.interceptor.ShiroSecuredInterceptor</class>
  </interceptors>
</beans>


ejb-jar.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd"
  version="3.1">
<interceptors>
  <interceptor>
    <interceptor-class>com.example.interceptor.ShiroSecuredInterceptor</interceptor-class>
    </interceptor>
  </interceptors>
  <assembly-descriptor>
    <interceptor-binding>
      <ejb-name>*</ejb-name>
    <interceptor-class>com.example.interceptor.ShiroSecuredInterceptor</interceptor-class>
    </interceptor-binding>
  </assembly-descriptor>
</ejb-jar>

web.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID"
  version="3.1">
<display-name>shiroTest</display-name>
<context-param>
  <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
  <param-value>true</param-value>
</context-param>
<welcome-file-list>
  <welcome-file>Login.xhtml</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
  </listener>
  <filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
    </filter>
  <filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
  </filter-mapping>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
</web-app>

//更新
终于让服务器重新上线,并且能够获得抛出异常

 [4/17/15 12:16:22:053 EEST] 00000043 SystemErr     R javax.naming.NameNotFoundException: Context: securityoffNode01Cell/nodes/securityoff/servers/server1, name: realms/ShiroRealm: First component in name realms/ShiroRealm not found. [Root exception is org.omg.CosNaming.NamingContextPackage.NotFound: IDL:omg.org/CosNaming/NamingContext/NotFound:1.0]

包含完整的堆栈跟踪很重要,我把它放在pastebin上一段时间。 http://pastebin.com/sANAqCJL

(意识到我用来在GlassFish上测试这个配置的项目是一个简单的战争项目,其中部署在WAS上的实际实现是在耳中。这些服务器之间可能相关或不相关。)

//更新2 阅读本文后(尚未完全阅读和测试): http://www-01.ibm.com/support/knowledgecenter/SS7JFU_7.0.0/com.ibm.websphere.express.iseries.doc/info/iseriesexp/ae/cejb_bindingsejbfp.html

我尝试使用一个名字:&#34; ejblocal:MockRealm&#34;。 好吧,这似乎没问题。不过继续这个问题,现在出现以下异常。

[4/17/15 13:17:47:536 EEST] 000000ac webapp        E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[com.ibm.ws.webcontainer.extension.DefaultExtensionProcessor]: java.lang.IllegalStateException: Unable to look up realm with jndi name 'ejblocal:MockRealm'.

看起来shiro.ini中使用的jndi名称仍然需要修复其他东西,但是&#39; ejbLocal:MockRealm&#34;或者&#34;简单地&#34; MockRealm&#34;不行。 我希望很快找到解决方案,然后我会发布一个真实的答案。

2 个答案:

答案 0 :(得分:0)

您是否尝试删除&#34; env&#34;你在这里传递的参数?

//InitialContext ic = new InitialContext(env); //OLD
InitialContext ic = new InitialContext(); //NEW

原因是,当Shiro试图查找&#34;&#34;领域/ ShiroRealm&#39;它将使用没有环境参数的InitialContext来实现。

如果您需要定义环境,则必须创建一个向Shiro提供相同属性的RealmFactory。

package com.acme.realm.jndi;

import java.util.Properties;

import javax.naming.Context;

public class WASJndiRealmFactory extends JndiRealmFactory {

    @Override
    public void setJndiNames (String commaDelimited) throws IllegalStateException {
        Properties p = new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");
        setJndiEnvironment(p);
        super.setJndiNames(commaDelimited);
    }
}

然后你必须更新你的shiro.ini&#39;引用新的RealmFactory。

[main]
realmFactory = com.acme.realm.jndi.WASJndiRealmFactory

答案 1 :(得分:0)

我出现了这个有点过时的问题。 我无法配置Shiro,因此它可以与WAS配合使用。相反,我手动将“范围”所需的公共数据放入JNDI上下文中。 通过这种方式,我能够在Shiro中查找实际应用程序所需的内容。
使用此解决方案,不再需要ShiroStartup。