You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by aj...@apache.org on 2008/12/31 18:32:17 UTC
svn commit: r730419 - in /incubator/jspwiki/trunk:
src/com/ecyrd/jspwiki/auth/ src/com/ecyrd/jspwiki/auth/login/
src/com/ecyrd/jspwiki/xmlrpc/ tests/com/ecyrd/jspwiki/
tests/com/ecyrd/jspwiki/workflow/
Author: ajaquith
Date: Wed Dec 31 09:32:14 2008
New Revision: 730419
URL: http://svn.apache.org/viewvc?rev=730419&view=rev
Log:
AuthenticationManager now handles LoginExceptions more gracefully and propagates them to the original caller instead of wrapping them in WikiSecurityExceptions.
Modified:
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/AuthenticationManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/UserManager.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/WikiSecurityException.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/login/WikiCallbackHandler.java
incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/xmlrpc/MetaWeblogHandler.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/TestEngine.java
incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/workflow/ApprovalWorkflowTest.java
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/AuthenticationManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/AuthenticationManager.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/AuthenticationManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/AuthenticationManager.java Wed Dec 31 09:32:14 2008
@@ -277,6 +277,7 @@
// If user not authenticated, check if container logged them in, or if
// there's an authentication cookie
+ Set<Principal> principals = null;
if ( !session.isAuthenticated() )
{
// Create a callback handler
@@ -290,15 +291,31 @@
throw new WikiSecurityException( e.getMessage() );
}
- // Execute the container login module, then (if that fails) the cookie auth module
- Set<Principal> principals = authenticationMgr.doJAASLogin( WebContainerLoginModule.class, handler, options );
- if ( principals.size() == 0 && authenticationMgr.allowsCookieAuthentication() )
+ // Execute the container login module
+ try
+ {
+ principals = authenticationMgr.doJAASLogin( WebContainerLoginModule.class, handler, options );
+ }
+ catch ( LoginException e )
{
- principals = authenticationMgr.doJAASLogin( CookieAuthenticationLoginModule.class, handler, options );
+ // Container credentials not supplied in request. Ok, try the auth cookie!
+ }
+
+ // Execute the cookie authentication module (if allowed)
+ if ( ( principals == null || principals.size() == 0 ) && authenticationMgr.allowsCookieAuthentication() )
+ {
+ try
+ {
+ principals = authenticationMgr.doJAASLogin( CookieAuthenticationLoginModule.class, handler, options );
+ }
+ catch( LoginException e )
+ {
+ // Authentication cookie not supplied in request. Ok, try the assertion cookie!
+ }
}
// If the container logged the user in successfully, tell the WikiSession (and add all of the Principals)
- if ( principals.size() > 0 )
+ if ( principals != null && principals.size() > 0 )
{
fireEvent( WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
for ( Principal principal : principals )
@@ -312,18 +329,34 @@
if ( !session.isAuthenticated() && authenticationMgr.allowsCookieAssertions() )
{
// Execute the cookie assertion login module
- Set<Principal> principals = authenticationMgr.doJAASLogin( CookieAssertionLoginModule.class, handler, options );
- if ( principals.size() > 0 )
+ try
+ {
+ principals = authenticationMgr.doJAASLogin( CookieAssertionLoginModule.class, handler, options );
+ if ( principals != null && principals.size() > 0 )
+ {
+ fireEvent( WikiSecurityEvent.LOGIN_ASSERTED, getLoginPrincipal( principals ), session);
+ }
+ }
+ catch( LoginException e )
{
- fireEvent( WikiSecurityEvent.LOGIN_ASSERTED, getLoginPrincipal( principals ), session);
+ // Assertion cookie not supplied in request. Ok, use the IP address!
}
}
// If user still anonymous, use the remote address
- if (session.isAnonymous() )
+ if ( session.isAnonymous() )
{
- Set<Principal> principals = authenticationMgr.doJAASLogin( AnonymousLoginModule.class, handler, options );
- if ( principals.size() > 0 )
+ try
+ {
+ principals = authenticationMgr.doJAASLogin( AnonymousLoginModule.class, handler, options );
+ }
+ catch( LoginException e )
+ {
+ // If the anonymous login didn't succeed, we have a genuine configuration problem!
+ e.printStackTrace();
+ throw new WikiSecurityException( e.getMessage() );
+ }
+ if ( principals != null && principals.size() > 0 )
{
fireEvent( WikiSecurityEvent.LOGIN_ANONYMOUS, getLoginPrincipal( principals ), session );
return true;
@@ -344,15 +377,21 @@
* class will be used. When the LoginModule's <code>initialize</code> method is invoked,
* an options Map populated by properties keys prefixed by {@link #PREFIX_LOGIN_MODULE_OPTIONS}
* will be passed as a parameter.
- * @param session the current wiki session; may not be null.
+ * @param session the current wiki session; may not be <code>null</code>.
* @param username The user name. This is a login name, not a WikiName. In
* most cases they are the same, but in some cases, they might
* not be.
* @param password the password
- * @return true, if the username/password is valid
- * @throws com.ecyrd.jspwiki.auth.WikiSecurityException if the Authorizer or UserManager cannot be obtained
+ * @return <code>true</code> if the username/password is valid; <code>false</code>
+ * if the LoginModule should be ignored, or the WikiSession was <code>null</code>
+ * @throws LoginException
+ * if the LoginModule's <code>login()</code> or <code>commit()</code> phases
+ * failed for any reason, including invalid credentials.
+ * @throws WikiSecurityException
+ * if the login failed for any other reason. The root-cause exception can
+ * be retrieved via {@link java.lang.Throwable#getCause()}
*/
- public final boolean login( WikiSession session, String username, String password ) throws WikiSecurityException
+ public final boolean login( WikiSession session, String username, String password ) throws WikiSecurityException, LoginException
{
if ( session == null )
{
@@ -374,7 +413,7 @@
// Execute the user's specified login module
Set<Principal> principals = doJAASLogin( m_loginModuleClass, handler, m_loginModuleOptions );
- if (principals.size() > 0)
+ if ( principals.size() > 0 )
{
fireEvent(WikiSecurityEvent.LOGIN_AUTHENTICATED, getLoginPrincipal( principals ), session );
for ( Principal principal : principals )
@@ -511,6 +550,8 @@
* then its {@link javax.security.auth.spi.LoginModule#initialize(Subject, CallbackHandler, Map, Map)}
* method is called. The parameters passed to <code>initialize</code> is a
* dummy Subject, an empty shared-state Map, and an options Map the caller supplies.
+ * If login succeeds, this method will return the Set of Principals. If it fails for any reason,
+ * including invalid credentials, it will throw a {@link javax.security.auth.login.LoginException}.
*
* @param clazz
* the LoginModule class to instantiate
@@ -519,10 +560,14 @@
* @param options
* a Map of key/value strings for initializing the LoginModule
* @return the set of Principals returned by the JAAS method {@link Subject#getPrincipals()}
+ * @throws LoginException
+ * if the LoginModule's <code>login()</code> or <code>commit()</code> phases
+ * failed for any reason, including invalid credentials.
* @throws WikiSecurityException
- * if the LoginModule could not be instantiated for any reason
+ * if the LoginModule could not be instantiated. The root-cause exception can
+ * be retrieved via {@link java.lang.Throwable#getCause()}
*/
- protected Set<Principal> doJAASLogin(Class<? extends LoginModule> clazz, CallbackHandler handler, Map<String,String> options) throws WikiSecurityException
+ protected Set<Principal> doJAASLogin(Class<? extends LoginModule> clazz, CallbackHandler handler, Map<String,String> options) throws WikiSecurityException, LoginException
{
// Instantiate the login module
LoginModule loginModule = null;
@@ -530,13 +575,13 @@
{
loginModule = clazz.newInstance();
}
- catch (InstantiationException e)
+ catch ( InstantiationException e )
{
- throw new WikiSecurityException(e.getMessage());
+ throw new WikiSecurityException( e.getMessage(), e );
}
- catch (IllegalAccessException e)
+ catch ( IllegalAccessException e )
{
- throw new WikiSecurityException(e.getMessage());
+ throw new WikiSecurityException( e.getMessage(), e );
}
// Initialize the LoginModule
@@ -544,23 +589,15 @@
loginModule.initialize( subject, handler, EMPTY_MAP, options );
// Try to log in:
- boolean loginSucceeded = false;
boolean commitSucceeded = false;
- try
- {
- loginSucceeded = loginModule.login();
- if (loginSucceeded)
- {
- commitSucceeded = loginModule.commit();
- }
- }
- catch (LoginException e)
+ boolean loginSucceeded = loginModule.login();
+ if ( loginSucceeded )
{
- // Login or commit failed! No principal for you!
+ commitSucceeded = loginModule.commit();
}
// If we successfully logged in & committed, return all the principals
- if (loginSucceeded && commitSucceeded)
+ if ( loginSucceeded && commitSucceeded )
{
return subject.getPrincipals();
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/UserManager.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/UserManager.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/UserManager.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/UserManager.java Wed Dec 31 09:32:14 2008
@@ -28,6 +28,7 @@
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
+import javax.security.auth.login.LoginException;
import javax.servlet.http.HttpServletRequest;
import org.apache.jspwiki.api.WikiException;
@@ -371,7 +372,7 @@
mgr.login( session, profile.getLoginName(), profile.getPassword() );
}
}
- catch ( WikiException e )
+ catch ( LoginException e )
{
throw new WikiSecurityException( e.getMessage() );
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/WikiSecurityException.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/WikiSecurityException.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/WikiSecurityException.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/WikiSecurityException.java Wed Dec 31 09:32:14 2008
@@ -23,23 +23,32 @@
import org.apache.jspwiki.api.WikiException;
/**
- * Indicates an authentication or authorization
- * error or exception.
- *
- * @author Erik Bunn
- * @since 2.0
+ * Indicates an authentication or authorization error or exception.
+ *
+ * @author Erik Bunn
+ * @since 2.0
*/
-public class WikiSecurityException
- extends WikiException
+public class WikiSecurityException extends WikiException
{
private static final long serialVersionUID = 3617293441285764405L;
/**
- * Constructs an exception.
- * @param msg the message to supply to the exception
+ * Constructs an exception.
+ *
+ * @param msg the message to supply to the exception
*/
public WikiSecurityException( String msg )
{
- super(msg);
+ super( msg );
+ }
+
+ /**
+ * Constructs an exception with a root cause.
+ * @param msg the message to supply to the exception
+ * @param cause the root cause
+ */
+ public WikiSecurityException( String msg, Throwable cause )
+ {
+ super( msg, cause );
}
}
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/login/WikiCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/login/WikiCallbackHandler.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/login/WikiCallbackHandler.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/auth/login/WikiCallbackHandler.java Wed Dec 31 09:32:14 2008
@@ -22,13 +22,12 @@
import java.io.IOException;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
+import javax.security.auth.callback.*;
+import com.ecyrd.jspwiki.WikiSession;
import com.ecyrd.jspwiki.auth.user.UserDatabase;
+import com.ecyrd.jspwiki.log.Logger;
+import com.ecyrd.jspwiki.log.LoggerFactory;
/**
* Handles logins made from inside the wiki application, rather than via the web
@@ -42,6 +41,8 @@
*/
public class WikiCallbackHandler implements CallbackHandler
{
+ private static final Logger log = LoggerFactory.getLogger(WikiCallbackHandler.class);
+
private final UserDatabase m_database;
private final String m_password;
@@ -84,6 +85,18 @@
{
( (PasswordCallback) callback ).setPassword( m_password.toCharArray() );
}
+ else if( callbacks[i] instanceof TextOutputCallback )
+ {
+ TextOutputCallback textOutputCb = (TextOutputCallback) callbacks[i];
+ String loginResult = textOutputCb.getMessage();
+ if( textOutputCb.getMessageType() == TextOutputCallback.ERROR )
+ {
+ log.error( loginResult );
+ throw new IOException( loginResult );
+ }
+
+ log.info( loginResult );
+ }
else
{
throw new UnsupportedCallbackException( callback );
Modified: incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/xmlrpc/MetaWeblogHandler.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/xmlrpc/MetaWeblogHandler.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/xmlrpc/MetaWeblogHandler.java (original)
+++ incubator/jspwiki/trunk/src/com/ecyrd/jspwiki/xmlrpc/MetaWeblogHandler.java Wed Dec 31 09:32:14 2008
@@ -23,6 +23,8 @@
import java.io.ByteArrayInputStream;
import java.util.*;
+import javax.security.auth.login.LoginException;
+
import com.ecyrd.jspwiki.log.Logger;
import com.ecyrd.jspwiki.log.LoggerFactory;
@@ -106,6 +108,10 @@
{
throw new XmlRpcException( 1, e.getMessage(), e );
}
+ catch( LoginException e )
+ {
+ throw new XmlRpcException( 1, e.getMessage(), e );
+ }
return;
}
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/TestEngine.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/TestEngine.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/TestEngine.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/TestEngine.java Wed Dec 31 09:32:14 2008
@@ -25,6 +25,7 @@
import java.util.Map;
import java.util.Properties;
+import javax.security.auth.login.LoginException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@@ -82,7 +83,7 @@
* @return the wiki session
* @throws WikiSecurityException
*/
- public WikiSession adminSession() throws WikiSecurityException
+ public WikiSession adminSession() throws WikiSecurityException, LoginException
{
if ( m_adminWikiSession == null )
{
@@ -118,7 +119,7 @@
* @return the wiki session
* @throws WikiSecurityException
*/
- public WikiSession janneSession() throws WikiSecurityException
+ public WikiSession janneSession() throws WikiSecurityException, LoginException
{
if ( m_janneWikiSession == null )
{
@@ -344,9 +345,16 @@
// Build new request and associate our admin session
MockHttpServletRequest request = newHttpRequest();
WikiSession wikiSession = SessionMonitor.getInstance( this ).find( request.getSession() );
- this.getAuthenticationManager().login( wikiSession,
- Users.ADMIN,
- Users.ADMIN_PASS );
+ try
+ {
+ this.getAuthenticationManager().login( wikiSession,
+ Users.ADMIN,
+ Users.ADMIN_PASS );
+ }
+ catch( LoginException e )
+ {
+ throw new WikiException( e.getMessage(), e );
+ }
// Create page and wiki context
WikiPage page = createPage( WikiName.valueOf( pageName ) );
@@ -360,9 +368,16 @@
// Build new request and associate our Janne session
MockHttpServletRequest request = newHttpRequest();
WikiSession wikiSession = SessionMonitor.getInstance( this ).find( request.getSession() );
- this.getAuthenticationManager().login( wikiSession,
- Users.JANNE,
- Users.JANNE_PASS );
+ try
+ {
+ this.getAuthenticationManager().login( wikiSession,
+ Users.JANNE,
+ Users.JANNE_PASS );
+ }
+ catch( LoginException e )
+ {
+ throw new WikiException( e.getMessage(), e );
+ }
// Create page and wiki context
WikiPage page = createPage( WikiName.valueOf( pageName ) );
@@ -443,7 +458,7 @@
* @return the initialized round trip
* @throws WikiSecurityException
*/
- public MockRoundtrip authenticatedTrip( String user, String password, Class<? extends WikiActionBean> beanClass ) throws WikiSecurityException
+ public MockRoundtrip authenticatedTrip( String user, String password, Class<? extends WikiActionBean> beanClass ) throws WikiSecurityException, LoginException
{
MockServletContext servletContext = (MockServletContext)getServletContext();
if ( servletContext.getFilters().size() == 0 )
Modified: incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/workflow/ApprovalWorkflowTest.java
URL: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/workflow/ApprovalWorkflowTest.java?rev=730419&r1=730418&r2=730419&view=diff
==============================================================================
--- incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/workflow/ApprovalWorkflowTest.java (original)
+++ incubator/jspwiki/trunk/tests/com/ecyrd/jspwiki/workflow/ApprovalWorkflowTest.java Wed Dec 31 09:32:14 2008
@@ -180,7 +180,7 @@
assertEquals( notification, w.getHistory().get( 2 ) );
}
- public void testSaveWikiPageWithApproval() throws WikiException
+ public void testSaveWikiPageWithApproval() throws Exception
{
// Create a sample test page and try to save it
String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();
@@ -212,7 +212,7 @@
m_engine.deletePage( pageName );
}
- public void testSaveWikiPageWithRejection() throws WikiException
+ public void testSaveWikiPageWithRejection() throws Exception
{
// Create a sample test page and try to save it
String pageName = "SaveWikiPageWorkflow-Test" + System.currentTimeMillis();