parent
e8c0e74498
commit
ceb339d2e0
|
@ -1,102 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.adapters.cas;
|
||||
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationManager;
|
||||
|
||||
import org.springframework.security.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Provides actual CAS authentication by delegation to an <code>AuthenticationManager</code>.<P>Do not use this
|
||||
* class directly. Instead configure CAS to use the {@link CasPasswordHandlerProxy}.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id:CasPasswordHandler.java 2151 2007-09-22 11:54:13Z luke_t $
|
||||
*/
|
||||
public final class CasPasswordHandler implements InitializingBean {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CasPasswordHandler.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (this.authenticationManager == null) {
|
||||
throw new IllegalArgumentException("An AuthenticationManager is required");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by <code>CasPasswordHandlerProxy</code> for individual authentication requests.<P>Delegates to
|
||||
* the configured <code>AuthenticationManager</code>.</p>
|
||||
*
|
||||
* @param servletRequest as provided by CAS
|
||||
* @param username provided to CAS
|
||||
* @param password provided to CAS
|
||||
*
|
||||
* @return whether authentication was successful or not
|
||||
*/
|
||||
public boolean authenticate(ServletRequest servletRequest, String username, String password) {
|
||||
if ((username == null) || "".equals(username)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
password = "";
|
||||
}
|
||||
|
||||
Authentication request = new UsernamePasswordAuthenticationToken(username.toString(), password.toString());
|
||||
Authentication response = null;
|
||||
|
||||
try {
|
||||
response = authenticationManager.authenticate(request);
|
||||
} catch (AuthenticationException failed) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " failed: " + failed.toString());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Authentication request for user: " + username + " successful");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public AuthenticationManager getAuthenticationManager() {
|
||||
return authenticationManager;
|
||||
}
|
||||
|
||||
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.adapters.cas;
|
||||
|
||||
import edu.yale.its.tp.cas.auth.PasswordHandler;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Enables CAS to use the Spring Security for authentication.<P>This class works along with {@link
|
||||
* CasPasswordHandler} to enable users to easily migrate from stand-alone Spring Security deployments to
|
||||
* enterprise-wide CAS deployments.</p>
|
||||
* <p>It should be noted that Spring Security will operate as a CAS client irrespective of the
|
||||
* <code>PasswordHandler</code> used on the CAS server. In other words, this class need <B>not</B> be used on the CAS
|
||||
* server if not desired. It exists solely for the convenience of users wishing have CAS delegate to a Spring Security-based
|
||||
* <code>AuthenticationManager</code>.</p>
|
||||
* <p>This class works requires a properly configured <code>CasPasswordHandler</code>. On the first authentication
|
||||
* request, the class will use Spring's {@link WebApplicationContextUtils#getRequiredWebApplicationContext(ServletContext)}
|
||||
* method to obtain an <code>ApplicationContext</code> instance, inside which must be a configured
|
||||
* <code>CasPasswordHandler</code> instance. The <code>CasPasswordHandlerProxy</code> will then delegate
|
||||
* authentication requests to that instance.</p>
|
||||
* <p>To configure CAS to use this class, edit CAS' <code>web.xml</code> and define the
|
||||
* <code>edu.yale.its.tp.cas.authHandler</code> context parameter with the value
|
||||
* <code>org.springframework.security.adapters.cas.CasPasswordHandlerProxy</code>.</p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id:CasPasswordHandlerProxy.java 2151 2007-09-22 11:54:13Z luke_t $
|
||||
*/
|
||||
public class CasPasswordHandlerProxy implements PasswordHandler {
|
||||
//~ Static fields/initializers =====================================================================================
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CasPasswordHandlerProxy.class);
|
||||
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
private ApplicationContext ctx;
|
||||
private CasPasswordHandler handler;
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
/**
|
||||
* Called by CAS when authentication is required.<P>Delegates to the <code>CasPasswordHandler</code>.</p>
|
||||
*
|
||||
* @param request as provided by CAS
|
||||
* @param username provided to CAS
|
||||
* @param password provided to CAS
|
||||
*
|
||||
* @return whether authentication was successful or not
|
||||
*
|
||||
* @throws IllegalArgumentException if the application context does not contain a <code>CasPasswordHandler</code>
|
||||
* or the <code>ServletRequest</code> was not of type <code>HttpServletRequest</code>
|
||||
*/
|
||||
public boolean authenticate(ServletRequest request, String username, String password) {
|
||||
if (ctx == null) {
|
||||
if (!(request instanceof HttpServletRequest)) {
|
||||
throw new IllegalArgumentException("Can only process HttpServletRequest");
|
||||
}
|
||||
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
|
||||
ctx = this.getContext(httpRequest);
|
||||
}
|
||||
|
||||
if (handler == null) {
|
||||
Map beans = ctx.getBeansOfType(CasPasswordHandler.class, true, true);
|
||||
|
||||
if (beans.size() == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Bean context must contain at least one bean of type CasPasswordHandler");
|
||||
}
|
||||
|
||||
String beanName = (String) beans.keySet().iterator().next();
|
||||
handler = (CasPasswordHandler) beans.get(beanName);
|
||||
}
|
||||
|
||||
return handler.authenticate(request, username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows test cases to override where application context obtained from.
|
||||
*
|
||||
* @param httpRequest which can be used to find the <code>ServletContext</code>
|
||||
*
|
||||
* @return the Spring application context
|
||||
*/
|
||||
protected ApplicationContext getContext(HttpServletRequest httpRequest) {
|
||||
return WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext());
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
Adapter to Yale Central Authentication Service (CAS).
|
||||
<p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.adapters.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasPasswordHandlerProxy}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CasPasswordHandlerProxyTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CasPasswordHandlerProxyTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasPasswordHandlerProxyTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasPasswordHandlerProxyTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testDetectsIfHttpServletRequestNotPassed() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/springframework/security/adapters/cas/applicationContext-valid.xml");
|
||||
|
||||
try {
|
||||
proxy.authenticate(null, "x", "y");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Can only process HttpServletRequest", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testDetectsMissingDelegate() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/springframework/security/adapters/cas/applicationContext-invalid.xml");
|
||||
|
||||
try {
|
||||
proxy.authenticate(new MockHttpServletRequest(), "x", "y");
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("Bean context must contain at least one bean of type CasPasswordHandler", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testNormalOperation() {
|
||||
CasPasswordHandlerProxy proxy = new MockCasPasswordHandlerProxy(
|
||||
"org/springframework/security/adapters/cas/applicationContext-valid.xml");
|
||||
assertTrue(proxy.authenticate(new MockHttpServletRequest(), "rod", "koala"));
|
||||
assertFalse(proxy.authenticate(new MockHttpServletRequest(), "rod", "WRONG_PASSWORD"));
|
||||
assertFalse(proxy.authenticate(new MockHttpServletRequest(), "INVALID_USER_NAME", "WRONG_PASSWORD"));
|
||||
}
|
||||
|
||||
//~ Inner Classes ==================================================================================================
|
||||
|
||||
/**
|
||||
* Mock object so that application context source can be specified.
|
||||
*/
|
||||
private class MockCasPasswordHandlerProxy extends CasPasswordHandlerProxy {
|
||||
private ApplicationContext ctx;
|
||||
|
||||
public MockCasPasswordHandlerProxy(String appContextLocation) {
|
||||
ctx = new ClassPathXmlApplicationContext(appContextLocation);
|
||||
}
|
||||
|
||||
private MockCasPasswordHandlerProxy() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected ApplicationContext getContext(HttpServletRequest httpRequest) {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.adapters.cas;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.security.MockAuthenticationManager;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Tests {@link CasPasswordHandler}.
|
||||
*
|
||||
* @author Ben Alex
|
||||
* @version $Id:CasPasswordHandlerTests.java 2151 2007-09-22 11:54:13Z luke_t $
|
||||
*/
|
||||
public class CasPasswordHandlerTests extends TestCase {
|
||||
//~ Constructors ===================================================================================================
|
||||
|
||||
public CasPasswordHandlerTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CasPasswordHandlerTests(String arg0) {
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(CasPasswordHandlerTests.class);
|
||||
}
|
||||
|
||||
public final void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testDeniesAccessWhenAuthenticationManagerThrowsException()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(false));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), "username", "password"));
|
||||
}
|
||||
|
||||
public void testDetectsEmptyAuthenticationManager()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
|
||||
try {
|
||||
handler.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("An AuthenticationManager is required", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testGettersSetters() {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(false));
|
||||
assertTrue(handler.getAuthenticationManager() != null);
|
||||
}
|
||||
|
||||
public void testGracefullyHandlesEmptyUsernamesAndPassword()
|
||||
throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
// If empty or null username we return false
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), "", "password"));
|
||||
assertFalse(handler.authenticate(new MockHttpServletRequest(), null, "password"));
|
||||
|
||||
// We authenticate with null passwords (they might not have one)
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", null));
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "user", ""));
|
||||
}
|
||||
|
||||
public void testNormalOperation() throws Exception {
|
||||
CasPasswordHandler handler = new CasPasswordHandler();
|
||||
handler.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
assertTrue(handler.authenticate(new MockHttpServletRequest(), "username", "password"));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue