Author: shane.bryzak(a)jboss.com
Date: 2008-06-07 05:40:12 -0400 (Sat, 07 Jun 2008)
New Revision: 8349
Modified:
trunk/src/main/org/jboss/seam/security/Credentials.java
trunk/src/main/org/jboss/seam/security/Identity.java
trunk/src/main/org/jboss/seam/security/JpaTokenStore.java
trunk/src/main/org/jboss/seam/security/RememberMe.java
trunk/src/main/org/jboss/seam/security/RunAsOperation.java
trunk/src/main/org/jboss/seam/security/jaas/SeamLoginModule.java
trunk/src/main/org/jboss/seam/security/management/action/RoleAction.java
Log:
JBSEAM-2079
Modified: trunk/src/main/org/jboss/seam/security/Credentials.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Credentials.java 2008-06-07 00:25:03 UTC (rev
8348)
+++ trunk/src/main/org/jboss/seam/security/Credentials.java 2008-06-07 09:40:12 UTC (rev
8349)
@@ -76,7 +76,7 @@
public boolean isSet()
{
- return username != null && password != null;
+ return getUsername() != null && password != null;
}
public boolean isInvalid()
Modified: trunk/src/main/org/jboss/seam/security/Identity.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/Identity.java 2008-06-07 00:25:03 UTC (rev
8348)
+++ trunk/src/main/org/jboss/seam/security/Identity.java 2008-06-07 09:40:12 UTC (rev
8349)
@@ -76,8 +76,10 @@
private Principal principal;
private Subject subject;
- private RememberMe rememberMe;
+ private RememberMe rememberMe;
+ private boolean systemOp;
+
private String jaasConfigName = null;
private List<String> preAuthenticationRoles = new ArrayList<String>();
@@ -259,7 +261,7 @@
{
try
{
- if (Events.exists()) Events.instance().raiseEvent(EVENT_QUIET_LOGIN, this);
+ if (Events.exists()) Events.instance().raiseEvent(EVENT_QUIET_LOGIN);
// Ensure that we haven't been authenticated as a result of the
EVENT_QUIET_LOGIN event
if (!isLoggedIn(false))
@@ -354,7 +356,9 @@
preAuthenticationRoles.clear();
}
- if (Events.exists()) Events.instance().raiseEvent(EVENT_POST_AUTHENTICATE, this);
+ credentials.setPassword(null);
+
+ if (Events.exists()) Events.instance().raiseEvent(EVENT_POST_AUTHENTICATE, this);
}
/**
@@ -398,6 +402,7 @@
public boolean hasRole(String role)
{
if (!securityEnabled) return true;
+ if (systemOp) return true;
isLoggedIn(true);
@@ -509,6 +514,8 @@
*/
public void checkPermission(String name, String action, Object...arg)
{
+ if (systemOp) return;
+
isLoggedIn(true);
if ( !hasPermission(name, action, arg) )
@@ -529,6 +536,8 @@
public void checkPermission(Object target, String action)
{
+ if (systemOp) return;
+
isLoggedIn(true);
if ( !hasPermission(target, action) )
@@ -557,11 +566,8 @@
*/
public boolean hasPermission(String name, String action, Object...arg)
{
- if (!securityEnabled)
- {
- return true;
- }
-
+ if (!securityEnabled) return true;
+ if (systemOp) return true;
if (permissionMapper == null) return false;
if (arg != null)
@@ -581,11 +587,8 @@
public boolean hasPermission(Object target, String action)
{
- if (!securityEnabled)
- {
- return true;
- }
-
+ if (!securityEnabled) return true;
+ if (systemOp) return true;
if (permissionMapper == null) return false;
return permissionMapper.resolvePermission(target, action);
@@ -692,10 +695,13 @@
principal = operation.getPrincipal();
subject = operation.getSubject();
+ systemOp = operation.isSystemOperation();
+
operation.execute();
}
finally
{
+ systemOp = false;
principal = savedPrincipal;
subject = savedSubject;
}
Modified: trunk/src/main/org/jboss/seam/security/JpaTokenStore.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/JpaTokenStore.java 2008-06-07 00:25:03 UTC (rev
8348)
+++ trunk/src/main/org/jboss/seam/security/JpaTokenStore.java 2008-06-07 09:40:12 UTC (rev
8349)
@@ -100,7 +100,10 @@
public void invalidateToken(String username, String value)
{
Object token = lookupToken(username, value);
- lookupEntityManager().remove(token);
+ if (token != null)
+ {
+ lookupEntityManager().remove(token);
+ }
}
public void invalidateAll(String username)
Modified: trunk/src/main/org/jboss/seam/security/RememberMe.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RememberMe.java 2008-06-07 00:25:03 UTC (rev
8348)
+++ trunk/src/main/org/jboss/seam/security/RememberMe.java 2008-06-07 09:40:12 UTC (rev
8349)
@@ -3,7 +3,10 @@
import static org.jboss.seam.ScopeType.SESSION;
import static org.jboss.seam.annotations.Install.BUILT_IN;
+import java.io.Serializable;
import java.rmi.server.UID;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
import javax.faces.context.FacesContext;
@@ -33,7 +36,7 @@
@Scope(SESSION)
@Install(precedence = BUILT_IN, classDependencies =
"javax.faces.context.FacesContext")
@BypassInterceptors
-public class RememberMe
+public class RememberMe implements Serializable
{
class UsernameSelector extends Selector
{
@@ -84,10 +87,19 @@
public DecodedToken(String cookieValue)
{
- String decoded = new String(Base64.decode(cookieValue));
-
- username = decoded.substring(0, decoded.indexOf(':'));
- value = decoded.substring(decoded.indexOf(':') + 1);
+ if (cookieValue != null)
+ {
+ try
+ {
+ String decoded = new String(Base64.decode(cookieValue));
+ username = decoded.substring(0, decoded.indexOf(':'));
+ value = decoded.substring(decoded.indexOf(':') + 1);
+ }
+ catch (Exception ex)
+ {
+ // swallow
+ }
+ }
}
public String getUsername()
@@ -136,8 +148,16 @@
if (this.enabled != enabled)
{
this.enabled = enabled;
- usernameSelector.setCookieEnabled(enabled);
- usernameSelector.setDirty();
+ if (mode.equals(Mode.usernameOnly))
+ {
+ usernameSelector.setCookieEnabled(enabled);
+ usernameSelector.setDirty();
+ }
+ else if (mode.equals(Mode.autoLogin))
+ {
+ tokenSelector.setCookieEnabled(enabled);
+ tokenSelector.setDirty();
+ }
}
}
@@ -216,7 +236,7 @@
tokenSelector.setCookiePath(ctx.getExternalContext().getRequestContextPath());
}
- String token = usernameSelector.getCookieValue();
+ String token = tokenSelector.getCookieValue();
if (token != null)
{
setEnabled(true);
@@ -237,29 +257,59 @@
}
}
+ /**
+ * I hate these hacks...
+ */
+ private class BoolWrapper
+ {
+ boolean value;
+ }
+
@Observer(Identity.EVENT_QUIET_LOGIN)
- public void quietLogin(Identity identity)
+ public void quietLogin()
{
+ final Identity identity = Identity.instance();
+
if (mode.equals(Mode.autoLogin) && isEnabled())
{
+ final String username = identity.getCredentials().getUsername();
+ final BoolWrapper userEnabled = new BoolWrapper();
+ final List<String> roles = new ArrayList<String>();
+
// Double check our credentials again
- if (tokenStore.validateToken(identity.getCredentials().getUsername(),
- identity.getCredentials().getPassword()))
- {
- // Success, authenticate the user (if their account is enabled)
- if
(IdentityManager.instance().isUserEnabled(identity.getCredentials().getUsername()))
+ if (tokenStore.validateToken(username,
identity.getCredentials().getPassword()))
+ {
+ new RunAsOperation(true) {
+ @Override
+ public void execute()
+ {
+ if (IdentityManager.instance().isUserEnabled(username))
+ {
+ userEnabled.value = true;
+
+ for (String role :
IdentityManager.instance().getImpliedRoles(username))
+ {
+ roles.add(role);
+ }
+ }
+ }
+ }.run();
+
+ if (userEnabled.value)
{
- identity.getSubject().getPrincipals().add(new SimplePrincipal(
- identity.getCredentials().getUsername()));
- // And populate the roles
- for (String role : IdentityManager.instance().getImpliedRoles(
- identity.getCredentials().getUsername()))
+ identity.unAuthenticate();
+ identity.preAuthenticate();
+
+ // populate the roles
+ for (String role : roles)
{
identity.addRole(role);
}
-
+
+ // Set the principal
+ identity.getSubject().getPrincipals().add(new SimplePrincipal(username));
identity.postAuthenticate();
-
+
autoLoggedIn = true;
}
}
@@ -271,7 +321,7 @@
{
if (mode.equals(Mode.autoLogin))
{
- tokenSelector.getCookieValue();
+ tokenSelector.clearCookieValue();
}
}
@@ -292,8 +342,11 @@
DecodedToken decoded = new DecodedToken(tokenSelector.getCookieValue());
- // Invalidate the current token whether enabled or not
- tokenStore.invalidateToken(decoded.getUsername(), decoded.getValue());
+ // Invalidate the current token (if it exists) whether enabled or not
+ if (decoded.getUsername() != null)
+ {
+ tokenStore.invalidateToken(decoded.getUsername(), decoded.getValue());
+ }
if ( !enabled )
{
@@ -302,8 +355,9 @@
else
{
String value = generateTokenValue();
- tokenStore.createToken(decoded.getUsername(), value);
- tokenSelector.setCookieValueIfEnabled(encodeToken(decoded.getUsername(),
value));
+ tokenStore.createToken(identity.getPrincipal().getName(), value);
+ tokenSelector.setCookieEnabled(enabled);
+
tokenSelector.setCookieValueIfEnabled(encodeToken(identity.getPrincipal().getName(),
value));
}
}
}
@@ -311,7 +365,10 @@
@Observer(Credentials.EVENT_CREDENTIALS_UPDATED)
public void credentialsUpdated()
{
- usernameSelector.setDirty();
+ if (mode.equals(Mode.usernameOnly))
+ {
+ usernameSelector.setDirty();
+ }
}
/**
Modified: trunk/src/main/org/jboss/seam/security/RunAsOperation.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/RunAsOperation.java 2008-06-07 00:25:03 UTC
(rev 8348)
+++ trunk/src/main/org/jboss/seam/security/RunAsOperation.java 2008-06-07 09:40:12 UTC
(rev 8349)
@@ -20,6 +20,8 @@
private Set<String> roles;
+ private boolean systemOp = false;
+
public RunAsOperation()
{
principal = new SimplePrincipal(null);
@@ -27,6 +29,17 @@
roles = new HashSet<String>();
}
+ /**
+ * A system operation allows any security checks to pass
+ *
+ * @param systemOp
+ */
+ public RunAsOperation(boolean systemOp)
+ {
+ this();
+ systemOp = true;
+ }
+
public abstract void execute();
public Principal getPrincipal()
@@ -45,6 +58,11 @@
return this;
}
+ public boolean isSystemOperation()
+ {
+ return systemOp;
+ }
+
public void run()
{
for (String role : roles)
Modified: trunk/src/main/org/jboss/seam/security/jaas/SeamLoginModule.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/jaas/SeamLoginModule.java 2008-06-07 00:25:03
UTC (rev 8348)
+++ trunk/src/main/org/jboss/seam/security/jaas/SeamLoginModule.java 2008-06-07 09:40:12
UTC (rev 8349)
@@ -123,7 +123,7 @@
try
{
- boolean success = identityManager.authenticate(username,
identity.getPassword());
+ boolean success = identityManager.authenticate(username,
identity.getCredentials().getPassword());
if (success)
{
Modified: trunk/src/main/org/jboss/seam/security/management/action/RoleAction.java
===================================================================
--- trunk/src/main/org/jboss/seam/security/management/action/RoleAction.java 2008-06-07
00:25:03 UTC (rev 8348)
+++ trunk/src/main/org/jboss/seam/security/management/action/RoleAction.java 2008-06-07
09:40:12 UTC (rev 8349)
@@ -2,6 +2,7 @@
import static org.jboss.seam.ScopeType.CONVERSATION;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -14,7 +15,7 @@
@Name("org.jboss.seam.security.management.roleAction")
@Scope(CONVERSATION)
-public class RoleAction
+public class RoleAction implements Serializable
{
private String role;
private List<String> groups;