Как использовать JNDI с WAS (сервер приложений веб-сферы 8.5.5)

На самом деле я никогда раньше не использовал Web Sphere Application Server (8.5.5), и у меня нет реального опыта работы с JNDI в целом, и я даже работаю с Широ всего пару дней. Тем не менее мне нужно было бы получить пользовательскую область Широ для JNDI, чтобы и приложение, и Широ использовали общий экземпляр области (и чтобы область имела доступ к 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(...) ...
}

И у меня есть класс широ-стартапа следующим образом

@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 "realms/ShiroRealm" не найдено/не может быть использовано. (Я опубликую точное исключение позже, в настоящее время у меня проблемы с запуском сервера) Я не нашел, как следует давать имя (и это начинает занимать время, даже если я ожидаю, что такая информация будет легко найти), поэтому я публикую здесь в надежде, что кто-нибудь может дать мне совет.

(Примечание: я скопировал сюда только те части, которые считаю важными. При отладке кода при запуске в 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

Я попытался использовать имя: «ejblocal: MockRealm». Ну, это, кажется, нормально для него. Однако, продолжая эту же проблему, теперь появилось следующее исключение.

[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'.

Похоже, что имя jndi, используемое в shiro.ini, все еще нуждается в исправлении, но «ejbLocal: MockRealm» или «просто MockRealm» не подходит. Я надеюсь найти решение в ближайшее время, тогда я опубликую реальный ответ.


person Ville Myrskyneva    schedule 13.04.2015    source источник
comment
Связано: stackoverflow. ком/вопросы/18507629/   -  person Dave Jarvis    schedule 25.08.2017


Ответы (2)


Вы пытались удалить параметр env, который вы здесь передаете?

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

Причина в том, что когда Широ пытается найти "realms/ShiroRealm", он будет делать это с InitialContext без параметров среды.

Если требуется среда, которую вы определили, вам придется создать 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, чтобы он ссылался на новую RealmFactory.

[main]
realmFactory = com.acme.realm.jndi.WASJndiRealmFactory
person justin.hughey    schedule 22.04.2015

Мне пришло в голову просмотреть этот немного устаревший вопрос. Мне не удалось настроить Широ так, чтобы он работал с WAS. Вместо этого я вручную помещаю общие данные, которые нужны обеим "областям", в контекст JNDI. Таким образом, я смог найти в Широ то, что было нужно из фактического приложения.
С этим решением ShiroStartup больше не нужен.

person Ville Myrskyneva    schedule 11.08.2015