Haven't really used Web Sphere Application Server (8.5.5) before neither I have any actual experience with JNDI alltogether and I have even been working with Shiro only for couple of days. Still I would need to get a custom Shiro-realm to the JNDI so that both the application and the Shiro would share a common instance of the realm (and so that the realm would have access to ejb-resources via inject)
This is how I have done this so far:
WEB-INF/shiro.ini
[main]
realmFactory = org.apache.shiro.realm.jndi.JndiRealmFactory
realmFactory.jndiNames = realms/ShiroRealm
...
A custom Shiro-Realm (just mocks for now)
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(...) ...
}
A custom CredentialsMatcher
public class MockCredentialsMatcher implements CredentialsMatcher {
@Override public boolean doCredentialsMatch(...) ...
}
And I have a shiro-startup class as follows
@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();
}
}
}
I found a post earlier that suggest to do bridge the injection-scopes this way and actually this works, but only when this code is run on GlassFish (v4). I'm pretty sure this should also work with WAS 8.5.5, but can't resolve this error. (maybe trivial to someone, but ...)
The error I get is a complain that the jndi name "realms/ShiroRealm" is not found / can not be used. (I'll post the exact Exception later, currently having trouble running the server at all) I have not found how the name should be given (and this is starting to take time, even that I'd expect this kind of information would be easy to find), so I post in here in hopes that some one could advice me.
(Note: I copied here only the parts I thought relevant. When debugging the code when run on GlassFish, I get hits in all correct places when expected)
// Update (for completeness, though I do not think these are relevant for this question)
The contents of 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>
The contents of 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>
The constents of 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>
// UPDATE
finally got the server back online and was able to get the Exception thrown
[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]
Incase the full stack trace is important, I put it on the pastebin for a while. http://pastebin.com/sANAqCJL
(Realized that the project that I used to test this configuration on GlassFish is a simple 'war'-project where the actual implementation deployed on WAS is in ear. May or may not be relevant between these servers.)
// UPDATE 2 After reading this (not completely yet, still reading and testing): http://www-01.ibm.com/support/knowledgecenter/SS7JFU_7.0.0/com.ibm.websphere.express.iseries.doc/info/iseriesexp/ae/cejb_bindingsejbfp.html
I tried using a name: "ejblocal:MockRealm". Well, this seems to be ok for it. However continued with this same issue, the following Exception is now.
[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'.
It looks like the jndi name used in shiro.ini still needs to fixed something else, but the 'ejbLocal:MockRealm" or "simply "MockRealm" is not ok. I hope to find solution soon, I will post a real answer then.
I occured to browse this a bit dated question.
I could not configure the Shiro so that it worked with WAS. Instead I put manually the common data that both "scopes" needed into the JNDI context.
This way I was able to lookup in Shiro the things that were needed from the actual application.
With this solution the ShiroStartup was no longer needed.