Update itest/web to use Servelt 3.1
Previously itest/web used Servlet 2.5 which Spring 5 is not compatabile with. This commit removes unnecessary tests (ones that were already covered) and converts the remaining tests to MockMvc using the provided servlet version. Issue gh-4080
This commit is contained in:
parent
1222fc5f10
commit
c1e9140940
|
@ -7,31 +7,18 @@ dependencies {
|
|||
|
||||
testCompile project(':spring-security-core'),
|
||||
project(':spring-security-web'),
|
||||
project(':spring-security-taglibs'),
|
||||
project(':spring-security-test'),
|
||||
"org.springframework:spring-beans:$springVersion",
|
||||
"org.springframework:spring-webmvc:$springVersion",
|
||||
"org.mortbay.jetty:jetty-util:$jettyVersion",
|
||||
"org.testng:testng:6.8.21"
|
||||
testCompile ("org.mortbay.jetty:jetty:$jettyVersion") {
|
||||
}
|
||||
testCompile ('net.sourceforge.jwebunit:jwebunit-core:2.2') {
|
||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||
exclude group: 'regexp', module: 'regexp'
|
||||
}
|
||||
"org.springframework:spring-test:$springVersion"
|
||||
|
||||
testRuntime project(':spring-security-config'),
|
||||
project(':spring-security-ldap'),
|
||||
"org.mortbay.jetty:jsp-2.1-jetty:$jettyVersion",
|
||||
testRuntime ('net.sourceforge.jwebunit:jwebunit-htmlunit-plugin:2.2') {
|
||||
exclude group: 'javax.servlet', module: 'servlet-api'
|
||||
}
|
||||
project(':spring-security-ldap')
|
||||
}
|
||||
|
||||
integrationTest {
|
||||
useTestNG();
|
||||
options {
|
||||
jvmArgs = ["-ea", '-Xms128m', '-Xmx500m']
|
||||
systemProperties = ['webapp.dir': "$projectDir/src/main/webapp"]
|
||||
}
|
||||
maxParallelForks = 1
|
||||
}
|
||||
|
|
|
@ -15,26 +15,14 @@
|
|||
*/
|
||||
package org.springframework.security.integration;
|
||||
|
||||
import java.util.List;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import net.sourceforge.jwebunit.junit.WebTester;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
import org.mortbay.jetty.webapp.WebAppContext;
|
||||
import org.springframework.security.web.session.HttpSessionEventPublisher;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.ContextLoaderListener;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.AfterMethod;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.junit.After;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.support.XmlWebApplicationContext;
|
||||
|
||||
/**
|
||||
* Base class which allows the application to be started with a particular Spring
|
||||
|
@ -45,131 +33,29 @@ import org.testng.annotations.BeforeMethod;
|
|||
* @author Luke Taylor
|
||||
*/
|
||||
public abstract class AbstractWebServerIntegrationTests {
|
||||
private Server server;
|
||||
private final Object SERVER_LOCK = new Object();
|
||||
protected final WebTester tester = new WebTester();
|
||||
protected ConfigurableApplicationContext context;
|
||||
|
||||
/**
|
||||
* Override to set the application context files that should be loaded or return null
|
||||
* to use web.xml.
|
||||
*/
|
||||
protected abstract String getContextConfigLocations();
|
||||
|
||||
protected String getContextPath() {
|
||||
return "/testapp";
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public void startServer() throws Exception {
|
||||
synchronized (SERVER_LOCK) {
|
||||
if (server == null) {
|
||||
// System.setProperty("DEBUG", "true");
|
||||
// System.setProperty("VERBOSE", "true");
|
||||
// System.setProperty("IGNORED", "true");
|
||||
server = new Server(0);
|
||||
server.addHandler(createWebContext());
|
||||
server.start();
|
||||
}
|
||||
@After
|
||||
public void close() {
|
||||
if(context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private WebAppContext createWebContext() {
|
||||
String webappDir = System.getProperty("webapp.dir");
|
||||
|
||||
WebAppContext webCtx = new WebAppContext(webappDir == null ? "src/main/webapp"
|
||||
: webappDir, getContextPath());
|
||||
|
||||
if (StringUtils.hasText(getContextConfigLocations())) {
|
||||
webCtx.addEventListener(new ContextLoaderListener());
|
||||
webCtx.addEventListener(new HttpSessionEventPublisher());
|
||||
webCtx.getInitParams().put("contextConfigLocation",
|
||||
getContextConfigLocations());
|
||||
protected final MockMvc createMockMvc(String... configLocations) throws Exception {
|
||||
if(this.context != null) {
|
||||
throw new IllegalStateException("context is already loaded");
|
||||
}
|
||||
|
||||
ServletHolder servlet = new ServletHolder();
|
||||
servlet.setName("testapp");
|
||||
servlet.setClassName(DispatcherServlet.class.getName());
|
||||
webCtx.addServlet(servlet, "*.htm");
|
||||
XmlWebApplicationContext context = new XmlWebApplicationContext();
|
||||
context.setConfigLocations(configLocations);
|
||||
context.setServletContext(new MockServletContext());
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
|
||||
return webCtx;
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public void stopServer() throws Exception {
|
||||
synchronized (SERVER_LOCK) {
|
||||
if (server != null) {
|
||||
server.stop();
|
||||
}
|
||||
server = null;
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
public void initializeTester() {
|
||||
tester.getTestContext().setBaseUrl(getBaseUrl());
|
||||
}
|
||||
|
||||
@AfterMethod
|
||||
public void resetWebConversation() {
|
||||
tester.closeBrowser();
|
||||
tester.setTestContext(null);
|
||||
}
|
||||
|
||||
protected final String getBaseUrl() {
|
||||
int port = server.getConnectors()[0].getLocalPort();
|
||||
return "http://localhost:" + port + getContextPath() + "/";
|
||||
}
|
||||
|
||||
protected final Object getBean(String beanName) {
|
||||
return getAppContext().getBean(beanName);
|
||||
}
|
||||
|
||||
protected final WebApplicationContext getAppContext() {
|
||||
ServletContext servletCtx = ((WebAppContext) server.getHandler())
|
||||
.getServletContext();
|
||||
WebApplicationContext appCtx = WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(servletCtx);
|
||||
return appCtx;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected Cookie getRememberMeCookie() {
|
||||
List<Cookie> cookies = (List<Cookie>) tester.getTestingEngine().getCookies();
|
||||
for (Cookie c : cookies) {
|
||||
if (c.getName().equals("remember-me")) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected final void submit() {
|
||||
tester.submit();
|
||||
}
|
||||
|
||||
protected final void beginAt(String url) {
|
||||
tester.beginAt(url);
|
||||
}
|
||||
|
||||
protected final void setTextField(String name, String value) {
|
||||
tester.setTextField(name, value);
|
||||
}
|
||||
|
||||
protected final void assertFormPresent() {
|
||||
tester.assertFormPresent();
|
||||
}
|
||||
|
||||
protected final void assertTextPresent(String text) {
|
||||
tester.assertTextPresent(text);
|
||||
}
|
||||
|
||||
// Security-specific utility methods
|
||||
|
||||
protected void login(String username, String password) {
|
||||
assertFormPresent();
|
||||
setTextField("username", username);
|
||||
setTextField("password", password);
|
||||
submit();
|
||||
return MockMvcBuilders
|
||||
.webAppContextSetup(context)
|
||||
.apply(springSecurity())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,25 +15,29 @@
|
|||
*/
|
||||
package org.springframework.security.integration;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
public class BasicAuthenticationTests extends AbstractWebServerIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security-basic.xml /WEB-INF/in-memory-provider.xml";
|
||||
@Test
|
||||
public void httpBasicWhenAuthenticationRequiredAndNotAuthenticatedThen401() throws Exception {
|
||||
MockMvc mockMvc = createMockMvc("classpath:/spring/http-security-basic.xml", "classpath:/spring/in-memory-provider.xml", "classpath:/spring/testapp-servlet.xml");
|
||||
mockMvc.perform(get("secure/index"))
|
||||
.andExpect(status().isUnauthorized());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicAuthenticationIsSuccessful() throws Exception {
|
||||
tester.setIgnoreFailingStatusCodes(true);
|
||||
beginAt("secure/index.html");
|
||||
// Ignore the 401
|
||||
tester.setIgnoreFailingStatusCodes(false);
|
||||
tester.assertHeaderEquals("WWW-Authenticate",
|
||||
"Basic realm=\"Spring Security Application\"");
|
||||
tester.getTestContext().setAuthorization("johnc", "johncspassword");
|
||||
beginAt("secure/index.html");
|
||||
public void httpBasicWhenProvidedThen200() throws Exception {
|
||||
MockMvc mockMvc = createMockMvc("classpath:/spring/http-security-basic.xml", "classpath:/spring/in-memory-provider.xml", "classpath:/spring/testapp-servlet.xml");
|
||||
MockHttpServletRequestBuilder request = get("/secure/index")
|
||||
.with(httpBasic("johnc", "johncspassword"));
|
||||
mockMvc.perform(request)
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,44 +15,93 @@
|
|||
*/
|
||||
package org.springframework.security.integration;
|
||||
|
||||
import net.sourceforge.jwebunit.junit.WebTester;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.session.SessionDestroyedEvent;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultHandler;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class ConcurrentSessionManagementTests extends AbstractWebServerIntegrationTests {
|
||||
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security-concurrency.xml /WEB-INF/in-memory-provider.xml";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void maxConcurrentLoginsValueIsRespected() throws Exception {
|
||||
System.out.println("Client: ******* First login ******* ");
|
||||
beginAt("secure/index.html");
|
||||
login("jimi", "jimispassword");
|
||||
// Login again
|
||||
System.out.println("Client: ******* Second login ******* ");
|
||||
WebTester tester2 = new WebTester();
|
||||
tester2.getTestContext().setBaseUrl(getBaseUrl());
|
||||
tester2.beginAt("secure/index.html");
|
||||
// seems to be a bug in checking for form here (it fails)
|
||||
// tester2.assertFormPresent();
|
||||
tester2.setTextField("username", "jimi");
|
||||
tester2.setTextField("password", "jimispassword");
|
||||
// tester2.submit() also fails to detect the form
|
||||
tester2.getTestingEngine().submit();
|
||||
tester2.assertTextPresent("Maximum sessions of 1 for this principal exceeded");
|
||||
final MockHttpSession session1 = new MockHttpSession();
|
||||
final MockHttpSession session2 = new MockHttpSession();
|
||||
|
||||
MockMvc mockMvc = createMockMvc("classpath:/spring/http-security-concurrency.xml","classpath:/spring/in-memory-provider.xml", "classpath:/spring/testapp-servlet.xml");
|
||||
|
||||
mockMvc.perform(get("secure/index").session(session1))
|
||||
.andExpect(status().is3xxRedirection());
|
||||
|
||||
MockHttpServletRequestBuilder login1 = login()
|
||||
.session(session1);
|
||||
mockMvc.
|
||||
perform(login1)
|
||||
.andExpect(authenticated().withUsername("jimi"));
|
||||
|
||||
|
||||
MockHttpServletRequestBuilder login2 = login()
|
||||
.session(session2);
|
||||
mockMvc.perform(login2)
|
||||
.andExpect(redirectedUrl("/login.jsp?login_error=true"));
|
||||
Exception exception = (Exception) session2.getAttribute("SPRING_SECURITY_LAST_EXCEPTION");
|
||||
assertThat(exception).isNotNull();
|
||||
assertThat(exception.getMessage()).contains("Maximum sessions of 1 for this principal exceeded");
|
||||
|
||||
// Now logout to kill first session
|
||||
tester.gotoPage("/logout");
|
||||
mockMvc.perform(post("/logout").with(csrf()))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andDo(new ResultHandler() {
|
||||
@SuppressWarnings("serial")
|
||||
@Override
|
||||
public void handle(MvcResult result) throws Exception {
|
||||
context.publishEvent(new SessionDestroyedEvent(session1) {
|
||||
@Override
|
||||
public List<SecurityContext> getSecurityContexts() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return session1.getId();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Try second session again
|
||||
tester2.setTextField("username", "jimi");
|
||||
tester2.setTextField("password", "jimispassword");
|
||||
// tester2.submit() also fails to detect the form
|
||||
tester2.getTestingEngine().submit();
|
||||
tester2.assertTextPresent("A Secure Page");
|
||||
login2 = login()
|
||||
.session(session2);
|
||||
mockMvc.perform(login2)
|
||||
.andExpect(authenticated().withUsername("jimi"));
|
||||
|
||||
mockMvc.perform(get("/secure/index").session(session2))
|
||||
.andExpect(content().string(containsString("A Secure Page")));
|
||||
}
|
||||
|
||||
private MockHttpServletRequestBuilder login() {
|
||||
return post("/login")
|
||||
.param("username", "jimi")
|
||||
.param("password", "jimispassword")
|
||||
.with(csrf());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import net.sourceforge.jwebunit.junit.WebTester;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class CustomConcurrentSessionManagementTests extends
|
||||
AbstractWebServerIntegrationTests {
|
||||
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security-custom-concurrency.xml /WEB-INF/in-memory-provider.xml";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void maxConcurrentLoginsValueIsRespected() throws Exception {
|
||||
beginAt("secure/index.html");
|
||||
login("jimi", "jimispassword");
|
||||
// Login again
|
||||
System.out.println("Client: ******* Second login ******* ");
|
||||
WebTester tester2 = new WebTester();
|
||||
tester2.getTestContext().setBaseUrl(getBaseUrl());
|
||||
tester2.beginAt("secure/index.html");
|
||||
tester2.setTextField("username", "jimi");
|
||||
tester2.setTextField("password", "jimispassword");
|
||||
tester2.setIgnoreFailingStatusCodes(true);
|
||||
tester2.submit();
|
||||
assertThat(tester2.getServerResponse()).contains(
|
||||
"Maximum sessions of 1 for this principal exceeded");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logoutClearsSessionRegistryAndAllowsSecondLogin() throws Exception {
|
||||
beginAt("secure/index.html");
|
||||
login("bessie", "bessiespassword");
|
||||
SessionRegistry reg = getAppContext().getBean(SessionRegistry.class);
|
||||
|
||||
tester.gotoPage("/logout");
|
||||
|
||||
// Login again
|
||||
System.out.println("Client: ******* Second login ******* ");
|
||||
WebTester tester2 = new WebTester();
|
||||
tester2.getTestContext().setBaseUrl(getBaseUrl());
|
||||
tester2.beginAt("secure/index.html");
|
||||
tester2.setTextField("username", "bessie");
|
||||
tester2.setTextField("password", "bessiespassword");
|
||||
tester2.setIgnoreFailingStatusCodes(true);
|
||||
tester2.submit();
|
||||
assertThat(tester2.getServerResponse()).contains("A secure page");
|
||||
}
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class InMemoryProviderWebAppTests extends AbstractWebServerIntegrationTests {
|
||||
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security.xml /WEB-INF/in-memory-provider.xml";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginFailsWithinvalidPassword() {
|
||||
beginAt("secure/index.html");
|
||||
login("jimi", "wrongPassword");
|
||||
assertTextPresent("Your login attempt was not successful");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginSucceedsWithCorrectPassword() {
|
||||
beginAt("secure/index.html");
|
||||
login("jimi", "jimispassword");
|
||||
assertTextPresent("A Secure Page");
|
||||
tester.gotoPage("/logout");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicAuthenticationIsSuccessful() throws Exception {
|
||||
tester.getTestContext().setAuthorization("johnc", "johncspassword");
|
||||
beginAt("secure/index.html");
|
||||
beginAt("secure/index.html");
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks use of <jsp:include> with parameters in the secured page.
|
||||
*/
|
||||
@Test
|
||||
public void savedRequestWithJspIncludeSeesCorrectParams() {
|
||||
beginAt("secure/secure1.jsp?x=0");
|
||||
login("jimi", "jimispassword");
|
||||
// Included JSP has params ?x=1&y=2
|
||||
assertTextPresent("Params: x=1, y=2");
|
||||
assertTextPresent("xcount=2");
|
||||
}
|
||||
|
||||
// SEC-1255
|
||||
@Test
|
||||
public void redirectToUrlWithSpecialCharsInFilenameWorksOk() throws Exception {
|
||||
beginAt("secure/file%3Fwith%3Fspecial%3Fchars.htm?someArg=1");
|
||||
login("jimi", "jimispassword");
|
||||
assertTextPresent("I'm file?with?special?chars.htm");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistentLoginIsSuccesful() throws Exception {
|
||||
beginAt("secure/index.html");
|
||||
tester.checkCheckbox("remember-me");
|
||||
login("jimi", "jimispassword");
|
||||
Cookie rememberMe = getRememberMeCookie();
|
||||
assertThat(rememberMe).isNotNull();
|
||||
tester.closeBrowser();
|
||||
|
||||
tester.getTestContext().addCookie(rememberMe);
|
||||
beginAt("secure/index.html");
|
||||
assertTextPresent("A Secure Page");
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public final class JspTaglibTests extends AbstractWebServerIntegrationTests {
|
||||
|
||||
@Override
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security.xml /WEB-INF/in-memory-provider.xml";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authenticationTagEscapingWorksCorrectly() {
|
||||
beginAt("secure/authenticationTagTestPage.jsp");
|
||||
login("theescapist<>&.", "theescapistspassword");
|
||||
String response = tester.getServerResponse();
|
||||
assertThat(response)
|
||||
.contains("This is the unescaped authentication name: theescapist<>&.");
|
||||
assertThat(response)
|
||||
.contains("This is the unescaped principal.username: theescapist<>&.");
|
||||
assertThat(response)
|
||||
.contains("This is the authentication name: theescapist<>&.");
|
||||
assertThat(response)
|
||||
.contains("This is the principal.username: theescapist<>&.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void authorizationTagEvaluatesExpressionCorrectlyAndWritesValueToVariable() {
|
||||
beginAt("secure/authorizationTagTestPage.jsp");
|
||||
login("bessie", "bessiespassword");
|
||||
String response = tester.getServerResponse();
|
||||
assertThat(response)
|
||||
.contains("Users can see this and 'allowed' variable is true.");
|
||||
assertThat(response).doesNotContain("Role X users (nobody) can see this.");
|
||||
assertThat(response).contains("Role X expression evaluates to false");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
*
|
||||
* 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.integration;
|
||||
|
||||
import org.testng.annotations.*;
|
||||
|
||||
/**
|
||||
* @author Luke Taylor
|
||||
*/
|
||||
public class LdapWebAppTests extends AbstractWebServerIntegrationTests {
|
||||
|
||||
protected String getContextConfigLocations() {
|
||||
return "/WEB-INF/http-security.xml /WEB-INF/ldap-provider.xml";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doSomething() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -27,8 +27,6 @@
|
|||
</session-management>
|
||||
|
||||
<remember-me key="doesntmatter" token-repository-ref="tokenRepo"/>
|
||||
|
||||
<csrf disabled="true"/>
|
||||
</http>
|
||||
|
||||
<beans:bean name="tokenRepo" class="org.springframework.security.web.authentication.rememberme.InMemoryTokenRepositoryImpl"/>
|
|
@ -17,18 +17,27 @@ package org.springframework.security.itest.web;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Controller
|
||||
@RestController
|
||||
public class TestController {
|
||||
|
||||
@RequestMapping(value = "/secure/file?with?special?chars.htm", method = RequestMethod.GET)
|
||||
public void sec1255TestUrl(HttpServletResponse response) throws IOException {
|
||||
response.getWriter().append("I'm file?with?special?chars.htm");
|
||||
public String sec1255TestUrl() throws IOException {
|
||||
return "I'm file?with?special?chars.htm";
|
||||
}
|
||||
|
||||
@RequestMapping("/")
|
||||
public String home() {
|
||||
return "home";
|
||||
}
|
||||
|
||||
@RequestMapping("/secure/index")
|
||||
@ResponseBody
|
||||
public String secure() {
|
||||
return "A Secure Page";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
<http pattern="/login.jsp" security="none" />
|
||||
|
||||
<http entry-point-ref="aep" use-expressions="false">
|
||||
<intercept-url pattern="/**" access="ROLE_DEVELOPER,ROLE_USER" />
|
||||
|
||||
<session-management session-authentication-strategy-ref="sas"/>
|
||||
<logout />
|
||||
|
||||
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
|
||||
<custom-filter position="FORM_LOGIN_FILTER" ref="myAuthFilter" />
|
||||
|
||||
<csrf disabled="true"/>
|
||||
</http>
|
||||
|
||||
<beans:bean id="aep" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
|
||||
<beans:constructor-arg value="/login.jsp" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="myAuthFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
|
||||
<beans:property name="sessionAuthenticationStrategy" ref="sas" />
|
||||
<beans:property name="authenticationManager" ref="authenticationManager" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
|
||||
<beans:constructor-arg ref="sessionRegistry" />
|
||||
<beans:constructor-arg value="/session-expired.htm" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
|
||||
<beans:constructor-arg>
|
||||
<beans:list>
|
||||
<beans:bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy">
|
||||
<beans:constructor-arg ref="sessionRegistry"/>
|
||||
<beans:property name="maximumSessions" value="1" />
|
||||
<beans:property name="exceptionIfMaximumExceeded" value="true" />
|
||||
</beans:bean>
|
||||
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy">
|
||||
</beans:bean>
|
||||
<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy">
|
||||
<beans:constructor-arg ref="sessionRegistry"/>
|
||||
</beans:bean>
|
||||
</beans:list>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
|
||||
|
||||
</beans:beans>
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
- LDAP Provider configuration snippet
|
||||
-
|
||||
-->
|
||||
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/security"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
|
||||
|
||||
<ldap-server ldif="classpath*:test-server.ldif"/>
|
||||
|
||||
<authentication-manager alias="authenticationManager">
|
||||
<ldap-authentication-provider user-search-filter="(uid={0})" group-role-attribute="ou" />
|
||||
</authentication-manager>
|
||||
|
||||
<ldap-user-service user-search-filter="(uid={0})" group-role-attribute="ou"/>
|
||||
|
||||
</beans:beans>
|
|
@ -1,150 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<taglib 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-jsptaglibrary_2_0.xsd"
|
||||
version="2.0">
|
||||
<description>Spring Security Authorization Tag Library</description>
|
||||
|
||||
<tlib-version>3.1</tlib-version>
|
||||
<short-name>security</short-name>
|
||||
<uri>http://www.springframework.org/security/tags</uri>
|
||||
|
||||
<tag>
|
||||
<description>
|
||||
A tag which outputs the body of the tag if the configured access expression
|
||||
evaluates to true for the currently authenticated principal.
|
||||
</description>
|
||||
<name>authorize</name>
|
||||
<tag-class>org.springframework.security.taglibs.authz.JspAuthorizeTag</tag-class>
|
||||
<body-content>JSP</body-content>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
A Spring-EL expression which is supported by the WebSecurityExpressionHandler
|
||||
in the application context. The latter will be used to evaluate the expression.
|
||||
</description>
|
||||
<name>access</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
A URL within the application. If the user has access to this URL (as determined by
|
||||
the AccessDecisionManager), the tag body will be evaluated. If not, it will
|
||||
be skipped.
|
||||
</description>
|
||||
<name>url</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
Can optionally be used to narrow down the HTTP method (typically GET or POST) to which the URL
|
||||
applies to. Only has any meaning when used in combination with the "url" attribute.
|
||||
</description>
|
||||
<name>method</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
</attribute>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
A page scoped variable into which the boolean result of the tag evaluation will be written, allowing the
|
||||
same condition to be reused subsequently in the page without re-evaluation.
|
||||
</description>
|
||||
<name>var</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
</attribute>
|
||||
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<description>
|
||||
Allows access to the current Authentication object.
|
||||
</description>
|
||||
<name>authentication</name>
|
||||
<tag-class>org.springframework.security.taglibs.authz.AuthenticationTag</tag-class>
|
||||
<body-content>empty</body-content>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
Property of the Authentication object which should be output. Supports nested
|
||||
properties. For example if the principal object is an instance of UserDetails,
|
||||
the property "principal.username" will return the username. Alternatively, using
|
||||
"name" will call getName method on the Authentication object directly.
|
||||
</description>
|
||||
<name>property</name>
|
||||
<required>true</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<description>
|
||||
Name of the exported scoped variable which will contain the
|
||||
evaluated property of the Authentication object.
|
||||
</description>
|
||||
<name>var</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<description>
|
||||
Set HTML escaping for this tag, as a boolean value.
|
||||
</description>
|
||||
<name>htmlEscape</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<description>
|
||||
Scope for var.
|
||||
</description>
|
||||
<name>scope</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
<tag>
|
||||
<description>
|
||||
Allows inclusion of a tag body if the current Authentication
|
||||
has one of the specified permissions to the presented
|
||||
domain object instance.
|
||||
</description>
|
||||
<name>accesscontrollist</name>
|
||||
<tag-class>org.springframework.security.taglibs.authz.AccessControlListTag</tag-class>
|
||||
<body-content>JSP</body-content>
|
||||
|
||||
<attribute>
|
||||
<description>
|
||||
A comma separated list of permissions, which will be converted to
|
||||
Permission instances by the configured PermissionFactory.
|
||||
</description>
|
||||
<name>hasPermission</name>
|
||||
<required>true</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<description>
|
||||
The actual domain object instance for which permissions
|
||||
are being evaluated.
|
||||
</description>
|
||||
<name>domainObject</name>
|
||||
<required>true</required>
|
||||
<rtexprvalue>true</rtexprvalue>
|
||||
</attribute>
|
||||
<attribute>
|
||||
<description>
|
||||
A page scoped variable into which the boolean result of the tag evaluation will be written, allowing the
|
||||
same condition to be reused subsequently in the page without re-evaluation.
|
||||
</description>
|
||||
<name>var</name>
|
||||
<required>false</required>
|
||||
<rtexprvalue>false</rtexprvalue>
|
||||
</attribute>
|
||||
</tag>
|
||||
|
||||
</taglib>
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
|
||||
<web-app 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/web-app_2_5.xsd" version="2.5">
|
||||
|
||||
<display-name>Integration Tests Webapp</display-name>
|
||||
|
||||
<filter>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
||||
</filter>
|
||||
|
||||
<filter-mapping>
|
||||
<filter-name>springSecurityFilterChain</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
<!-- Don't add a context loader listener or config location. These are set programmatically -->
|
||||
|
||||
</web-app>
|
|
@ -1,31 +0,0 @@
|
|||
<!-- Not used unless you declare a <form-login login-page="/login.jsp"/> element -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Custom Spring Security Login</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Custom Spring Security Login</h1>
|
||||
|
||||
<%
|
||||
if (request.getParameter("login_error") != null) {
|
||||
%>
|
||||
Your login attempt was not successful, try again. ${SPRING_SECURITY_LAST_EXCEPTION.message}<br/><br/>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
|
||||
<form action="login" method="POST">
|
||||
<table>
|
||||
<tr><td>User:</td><td><input type='text' name='username' value=''/></td></tr>
|
||||
<tr><td>Password:</td><td><input type='password' name='password'></td></tr>
|
||||
<tr><td><input type="checkbox" name="remember-me"></td><td>Don't ask for my password for two weeks</td></tr>
|
||||
<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
|
||||
<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,17 +0,0 @@
|
|||
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Authentication Tag Test Page</h1>
|
||||
|
||||
<ul>
|
||||
<li>This is the authentication name: <sec:authentication property="name"/></li>
|
||||
<li>This is the principal.username: <sec:authentication property="principal.username"/></li>
|
||||
<li>This is the unescaped authentication name: <sec:authentication property="name" htmlEscape="false"/></li>
|
||||
<li>This is the unescaped principal.username: <sec:authentication property="principal.username" htmlEscape="false"/></li>
|
||||
|
||||
</ul>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
|
||||
<html>
|
||||
<body>
|
||||
<h1>Authorization Tag Test Page</h1>
|
||||
|
||||
<sec:authorize access="hasRole('ROLE_USER')" var="allowed">
|
||||
Users can see this and 'allowed' variable is ${allowed}.
|
||||
</sec:authorize>
|
||||
|
||||
<sec:authorize access="hasRole('ROLE_X')" var="allowed">
|
||||
Role X users (nobody) can see this.
|
||||
</sec:authorize>
|
||||
|
||||
Role X expression evaluates to ${allowed}.
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>A secure page</title>
|
||||
</head>
|
||||
<body>
|
||||
A Secure Page.
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>A secure page</title>
|
||||
</head>
|
||||
<body>
|
||||
<jsp:include page="secure1body.jsp">
|
||||
<jsp:param name="x" value="1" />
|
||||
<jsp:param name="y" value="2" />
|
||||
</jsp:include>
|
||||
</body>
|
||||
</html>
|
|
@ -1,2 +0,0 @@
|
|||
Params: x=<%= request.getParameter("x") %>, y=<%= request.getParameter("y") %>
|
||||
xcount=<%= request.getParameterValues("x").length %>
|
Loading…
Reference in New Issue