Hi again,
Well, I did put a breakpoint at the RootInterceptor.invoke() method and it gets
hit.
I've also implemented the manual Identity.login(), even tested with
Identity.authenticate().
I've also verified that the @Restrict("#{s:hasRole('user')}") works if I access
the method from my JSF after I'm logged in.
Seems like I'm missing something here so I'll give you the whole enchillada!
Here's my Quartz Pojo Job
| public class SampleJob implements Job {
|
| private final Logger LOGGER = Logger.getLogger(this.getClass());
|
| public void execute(final JobExecutionContext theJobExecutionContext)
| throws JobExecutionException {
| this.LOGGER.info("Executing job with description: "
| +
theJobExecutionContext.getJobDetail().getDescription());
| LoginContext lc = null;
| try {
| // Begin Seam session
| Lifecycle.beginSession(new java.util.HashMap<String,
Object>());
|
| // External client login
| UsernamePasswordHandler handler = new
UsernamePasswordHandler(
| "user", "Demo987!");
| lc = new LoginContext("client-login", handler);
| lc.login();
|
| // Lookup EJB
| final TestSeamSecurityService service =
(TestSeamSecurityService) new InitialContext()
|
.lookup("sio/TestSeamSecurityServiceBean/local");
|
| // Any calls to secured resources now use the
username/password
| // identity
| service.login("user", "Demo987!");
|
| // Should fail because 'user' don't have the role
'admin'
| service.secure();
|
| // Clear and restore the previous identity
| service.logout();
| lc.logout();
| } catch (Exception e) {
| e.printStackTrace();
| } finally {
| // End Seam session
| Lifecycle.endSession(new java.util.HashMap<String,
Object>());
| }
| }
| }
|
And here's my Seam component using the @Restrict annotation (local business
interface omitted):
| @Stateful
| @SecurityDomain("sio")
| @Local(TestSeamSecurityService.class)
| @Name("echoService")
| public class TestSeamSecurityServiceBean implements TestSeamSecurityService
{
|
| @Logger
| private transient Log log;
|
| @Resource
| private SessionContext sessionContext;
|
| @RolesAllowed("user")
| public void login(final String theUsername, final String thePassword)
| throws LoginException {
| this.log.info("Entered 'login' method...");
| // Seam login
| Identity.instance().setUsername(theUsername);
| Identity.instance().setPassword(thePassword);
| Identity.instance().login();
| // Identity.instance().authenticate();
| this.log.info("Exiting 'login' method.");
| this.status();
| }
|
| public void logout() {
| Identity.instance().logout();
| }
|
| @Restrict("#{s:hasRole('admin')}")
| public void secure() {
| this.log.info("Entered 'secure' method.");
| this.status();
| }
|
| @Remove
| @Destroy
| public void destroy() {
| }
|
| private void status() {
| this.log.info("-=STATUS=-");
| this.log.info("Caller Principal = #0", this.sessionContext
| .getCallerPrincipal());
| this.log.info("Is Identity Security Enabled = #0", Identity
| .isSecurityEnabled());
| this.log.info("Identity Is Logged In = #0", Identity.instance()
| .isLoggedIn());
| this.log.info("Identity Has Role 'user' = #0",
Identity.instance()
| .hasRole("user"));
| this.log.info("Identity Has Role 'admin' = #0",
Identity.instance()
| .hasRole("admin"));
| }
|
| }
|
As you can see I've implemented the "standard Java EE security" using
@SecurityDomain annotation. The annotation @RolesAllowed works like a charm but
not @Restrict.
component.xml
| <?xml version="1.0" encoding="UTF-8"?>
| <components xmlns="http://jboss.com/products/seam/components"
| xmlns:core="http://jboss.com/products/seam/core"
| xmlns:persistence="http://jboss.com/products/seam/persistence"
| xmlns:security="http://jboss.com/products/seam/security"
| xmlns:drools="http://jboss.com/products/seam/drools"
| xmlns:async="http://jboss.com/products/seam/async"
| xmlns:web="http://jboss.com/products/seam/web"
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| xmlns:framework="http://jboss.com/products/seam/framework"
| xsi:schemaLocation="http://jboss.com/products/seam/core
http://jboss.com/products/seam/core-2.0.xsd
| http://jboss.com/products/seam/persistence
http://jboss.com/products/seam/persistence-2.0.xsd
| http://jboss.com/products/seam/components
http://jboss.com/products/seam/components-2.0.xsd
| http://jboss.com/products/seam/security
http://jboss.com/products/seam/security-2.0.xsd
| http://jboss.com/products/seam/async
http://jboss.com/products/seam/async-2.0.xsd
| http://jboss.com/products/seam/web
http://jboss.com/products/seam/web-2.0.xsd
| http://jboss.com/products/seam/framework
http://jboss.com/products/seam/framework-2.0.xsd
| http://jboss.com/products/seam/drools
http://jboss.com/products/seam/drools-2.0.xsd">
|
| <core:init jndi-pattern="sio/#{ejbName}/local" debug="true"
| transaction-management-enabled="true" />
|
| <persistence:managed-persistence-context name="entityManager"
| auto-create="true"
|
persistence-unit-jndi-name="java:/OracleSioEntityManagerFactory" />
|
| <core:manager conversation-timeout="600000"
| concurrent-request-timeout="500"
conversation-id-parameter="cid" />
|
| <!-- Default system JAAS configuration -->
| <security:identity
| authenticate-method="#{authenticator.authenticate}"
| jaas-config-name="sio" />
|
| <drools:rule-base name="securityRules">
| <drools:rule-files>
| <value>/META-INF/security.drl</value>
| </drools:rule-files>
| </drools:rule-base>
|
| <framework:entity-query name="roles" ejbql="select r from Role r" />
|
| <event type="org.jboss.seam.notLoggedIn">
| <action execute="#{redirect.captureCurrentView}" />
| </event>
|
| <event type="org.jboss.seam.postAuthenticate">
| <action execute="#{redirect.returnToCapturedView}" />
| </event>
|
| </components>
|
The Drools rules in security.drl only concerns entities not part of this
problem so I'm not including it and the orm.xml in this post. Does anyone feel
the need to see just tell me :-)
web.xml
| <?xml version="1.0" encoding="UTF-8"?>
|
| <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
| xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
| <!-- Initializes Quartz in the application server -->
|
| <servlet>
| <servlet-name>QuartzInitializer</servlet-name>
| <display-name>Quartz Initializer Servlet</display-name>
| <servlet-class>
| org.quartz.ee.servlet.QuartzInitializerServlet
| </servlet-class>
| <load-on-startup>2</load-on-startup>
| <init-param>
| <param-name>shutdown-on-unload</param-name>
| <param-value>true</param-value>
| </init-param>
| <init-param>
| <param-name>start-scheduler-on-load</param-name>
| <param-value>true</param-value>
| </init-param>
| </servlet>
|
| <!-- BEGIN: RichFaces -->
| <context-param>
| <param-name>org.richfaces.SKIN</param-name>
| <param-value>DEFAULT</param-value>
| </context-param>
|
| <filter>
| <display-name>RichFaces Filter</display-name>
| <filter-name>richfaces</filter-name>
| <filter-class>org.ajax4jsf.Filter</filter-class>
| </filter>
|
| <filter-mapping>
| <filter-name>richfaces</filter-name>
| <servlet-name>Faces Servlet</servlet-name>
| <dispatcher>REQUEST</dispatcher>
| <dispatcher>FORWARD</dispatcher>
| <dispatcher>INCLUDE</dispatcher>
| </filter-mapping>
|
| <!-- END: RichFaces -->
|
| <!-- Seam -->
|
| <listener>
| <listener-class>
| org.jboss.seam.servlet.SeamListener
| </listener-class>
| </listener>
|
| <servlet>
| <servlet-name>Seam Resource Servlet</servlet-name>
| <servlet-class>
| org.jboss.seam.servlet.ResourceServlet
| </servlet-class>
| </servlet>
|
| <servlet-mapping>
| <servlet-name>Seam Resource Servlet</servlet-name>
| <url-pattern>/seam/resource/*</url-pattern>
| </servlet-mapping>
|
| <filter>
| <filter-name>Seam Filter</filter-name>
| <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
| </filter>
|
| <filter-mapping>
| <filter-name>Seam Filter</filter-name>
| <url-pattern>/*</url-pattern>
| </filter-mapping>
|
| <context-param>
| <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
| <param-value>client</param-value>
| </context-param>
|
| <context-param>
| <param-name>facelets.DEVELOPMENT</param-name>
| <param-value>true</param-value>
| </context-param>
|
| <context-param>
| <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
| <param-value>.xhtml</param-value>
| </context-param>
|
| <servlet>
| <servlet-name>Faces Servlet</servlet-name>
| <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
| <load-on-startup>1</load-on-startup>
| </servlet>
|
| <!-- Faces Servlet Mapping -->
|
| <servlet-mapping>
| <servlet-name>Faces Servlet</servlet-name>
| <url-pattern>*.seam</url-pattern>
| </servlet-mapping>
|
| </web-app>
|
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_0.xsd"
| version="3.0">
|
| <interceptors>
| <interceptor>
| <interceptor-class>
| org.jboss.seam.ejb.SeamInterceptor
| </interceptor-class>
| </interceptor>
| </interceptors>
|
| <assembly-descriptor>
| <interceptor-binding>
| <ejb-name>*</ejb-name>
| <interceptor-class>
| org.jboss.seam.ejb.SeamInterceptor
| </interceptor-class>
| </interceptor-binding>
| </assembly-descriptor>
|
| </ejb-jar>
|
Here's my login-config.xml:
| <?xml version='1.0'?>
| <!DOCTYPE policy PUBLIC
| "-//JBoss//DTD JBOSS Security Config 3.0//EN"
| "http://www.jboss.org/j2ee/dtd/security_config.dtd">
|
| <policy>
|
| <!-- Used by clients within the application server VM such as mbeans
and servlets that access EJBs. -->
| <application-policy name = "client-login">
| <authentication>
| <login-module code = "org.jboss.security.ClientLoginModule"
| flag = "required">
| <!-- Any existing security context will be restored on logout
-->
| <module-option
name="restore-login-identity">true</module-option>
| <module-option name="multi-threaded">true</module-option>
| </login-module>
| </authentication>
| </application-policy>
|
| <!-- Default JBoss stuff omitted -->
|
| <!-- Security domain for SIO -->
| <application-policy name = "sio">
| <authentication>
| <login-module code =
"com.cybercomgroup.security.auth.jboss.SoxDatabaseServerLoginModule" flag =
"required">
| <module-option name = "dsJndiName">java:/OracleSio</module-option>
| <module-option name = "rolesQuery">SELECT role_name, 'Roles' FROM
principals JOIN roles ON principals.id = roles.id WHERE
principals.username=?</module-option>
| <module-option name = "principalsQuery">SELECT Password FROM
principals WHERE username=?</module-option>
| </login-module>
| </authentication>
| </application-policy>
|
| </policy>
|
And here the log output from a Quartz job execution:
| 13:41:00,025 INFO [SampleJob] Executing job with description: A sample job
doing nothing.
| 13:41:00,025 INFO [Contexts] starting up: org.jboss.seam.web.session
| 13:41:00,025 INFO [Contexts] starting up: org.jboss.seam.security.identity
| 13:41:00,756 INFO [RuleBase] parsing rules: /META-INF/security.drl
| 13:41:05,703 INFO [SoxDatabaseServerLoginModule] started login attempt
| 13:41:06,774 INFO [SoxDatabaseServerLoginModule] principal 'user' is
authenticated and active
| 13:41:06,774 INFO [SoxDatabaseServerLoginModule] days since last password
change = 65
| 13:41:06,804 INFO [SoxDatabaseServerLoginModule] authentication successful
= true
| 13:41:06,894 INFO [TestSeamSecurityServiceBean] Entered 'login' method...
| 13:41:06,894 INFO [SoxDatabaseServerLoginModule] started login attempt
| 13:41:06,945 INFO [SoxDatabaseServerLoginModule] principal 'user' is
authenticated and active
| 13:41:06,945 INFO [SoxDatabaseServerLoginModule] days since last password
change = 65
| 13:41:06,975 INFO [SoxDatabaseServerLoginModule] authentication successful
= true
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Exiting 'login' method.
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] -=STATUS=-
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Caller Principal = user
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Is Identity Security
Enabled = true
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Identity Is Logged In =
true
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Identity Has Role 'user' =
true
| 13:41:08,246 INFO [TestSeamSecurityServiceBean] Identity Has Role 'admin'
= false
|
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Entered 'secure' method.
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] -=STATUS=-
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Caller Principal = user
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Is Identity Security
Enabled = true
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Identity Is Logged In =
false
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Identity Has Role 'user' =
false
| 13:41:08,276 INFO [TestSeamSecurityServiceBean] Identity Has Role 'admin'
= false
|
As you can see the Identity is populated with the role 'user' when I perform a
"manual" login. But between the calls to method 'login' and then method
'secure' the Identity seems to lose its principal information.
And even worse - the @Restrict annotation doesn't kick in at all. Even though
the Identity doesn't seem to get its principals between calls the @Restrict
annotation should react to it and throw an exception because the Identity
doesn't contain the role required to call 'secure'.
Soon I'll have to implement this myself which sucks :-(
Cheers!
Regards, Andreas
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4108471#4108471
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4108471
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user