Security, SLSB, Webservice question
nthompson.nate.cimconsultants.com Feb 18, 2008 10:32 PMHi All,
I'm trying to add some web services components to a project I've been working on. The web services themselves have been easy to get going, but the security aspect is giving me some trouble.
I've implemented a login method in my web service stateless bean. I've also setup the identity authenticator and referenced it in components.xml. These both work, in so far as the authentication happens and returns true or false appropriately from the Indentity.instance().login call from my SLSB.
The problem comes when I make a subsequent call to the SLSB, to a method annotated with
@Restrict("#{identity.loggedIn}")
(or using
@Restrict("#{s:hasRole('Administrator')}")
... I always get a NotLoggedInException.
Am I supposed to be storing something in the session scope? I thought the Identity component handled this already?
Setup is jboss-4.2.2.GA, seam 2.0.1.ga, icefaces 1.7.0dr2.
Here's 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:security="http://jboss.com/products/seam/security" xmlns:transaction="http://jboss.com/products/seam/transaction" xmlns:web="http://jboss.com/products/seam/web" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.0.xsd http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.0.xsd"> <core:init jndi-pattern="STACS2/#{ejbName}/local" debug="true" /> <!-- conversation-timeout = 30 minutes --> <core:manager conversation-timeout="1800000" /> <component name="stacsDatabase" class="org.jboss.seam.persistence.ManagedPersistenceContext"> <property name="persistenceUnitJndiName"> java:/EntityManagerFactories/stacsData </property> </component> <security:identity authenticate-method="#{authenticator.authenticate}"/> </components>
Web service remote interface:
@Remote public interface TaskManagerServiceRemote { public boolean login(String userName, String password); public String restrictedAction(); }
Web service class:
@Stateless @WebService(name = "TaskManagerService", serviceName = "TaskManagerService") @SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL) @Name("taskManagerService") public class TaskManagerService implements TaskManagerServiceRemote { @WebMethod public boolean login( @WebParam(mode = Mode.IN, name = "userName") String userName, @WebParam(mode = Mode.IN, name = "password") String password) { Identity identity = Identity.instance(); identity.setUsername(userName); identity.setPassword(password); identity.login(); return identity.isLoggedIn(); } @WebMethod public @WebResult(name = "string") String restrictedAction() { StringBuilder sb = new StringBuilder(); Identity identity = Identity.instance(); sb.append("is security enabled: "); sb.append(Identity.isSecurityEnabled()); sb.append("\r\n"); sb.append("is remember me: "); sb.append(identity.isRememberMe()); sb.append("\r\n"); sb.append("is logged in: "); sb.append(identity.isLoggedIn()); sb.append("\r\n"); sb.append("has admin role: "); sb.append(identity.hasRole("Administrator")); return sb.toString(); throw new NotLoggedInException } }
Note that I've removed the @Restrict annotation here in an effort to see what is going on... The message I always get in my soap client is that security is enabled, but rememberme, loggedin, and has admin role are always false, no matter if I've logged in or not.
For good measure, hear's my Authenticator class:
@Name("authenticator") public class Authenticator { @In Identity identity; @In(create = true) private EntityManager stacsDatabase; @Logger private Log log; public boolean authenticate() { try { char[] plainPassword = identity.getPassword().toCharArray(); char[] encodedPassword = CommonUtils.encodePassword(plainPassword); User user = (User) stacsDatabase .createQuery( "from User where lower(userid) = :userid " + "and passwd_enc = :password " + "and deactivated = false") .setParameter("userid", identity.getUsername().toLowerCase()) .setParameter("password", String.valueOf(encodedPassword)) .getSingleResult(); if (user != null && user.getUserroleses() != null) { for (Userroles userRole : user.getUserroleses()) { Identity.instance().addRole(userRole.getRole().getRolename()); } } return true; } catch (NoResultException rne) { log.debug("authenticate: NoResultException!"); return false; } catch (NoSuchAlgorithmException nsae) { log.debug("authenticate: NoSuchAlgorithmException!"); return false; } } }
Thanks for your help!
Nate