diff --git a/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy b/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy deleted file mode 100644 index 900a94bbc7..0000000000 --- a/config/src/test/groovy/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.groovy +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright 2002-2013 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.config.annotation.web - -import org.springframework.security.core.userdetails.PasswordEncodedUser - -import javax.servlet.http.HttpServletResponse - -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.context.annotation.Configuration -import org.springframework.core.annotation.Order -import org.springframework.security.config.annotation.BaseSpringSpec -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder -import org.springframework.security.config.annotation.web.builders.HttpSecurity -import org.springframework.security.config.annotation.web.builders.WebSecurity -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter - -/** - * Demonstrate the samples - * - * @author Rob Winch - * - */ -public class SampleWebSecurityConfigurerAdapterTests extends BaseSpringSpec { - def "README HelloWorld Sample works"() { - setup: "Sample Config is loaded" - loadConfig(HelloWorldWebSecurityConfigurerAdapter) - when: - request.addHeader("Accept", "text/html") - springSecurityFilterChain.doFilter(request,response,chain) - then: - response.getRedirectedUrl() == "http://localhost/login" - when: "fail to log in" - super.setup() - request.addHeader("Accept", "text/html") - request.servletPath = "/login" - request.method = "POST" - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to login error page" - response.getRedirectedUrl() == "/login?error" - when: "login success" - super.setup() - request.servletPath = "/login" - request.method = "POST" - request.parameters.username = ["user"] as String[] - request.parameters.password = ["password"] as String[] - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to default succes page" - response.getRedirectedUrl() == "/" - } - - /** - * - * - * - * - * - * login-processing-url="/login" - * password-parameter="password" - * username-parameter="username" - * /> - * - * - * - * - * - * - * - * - * - * @author Rob Winch - */ - @EnableWebSecurity - public static class HelloWorldWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - @Override - protected void configure(AuthenticationManagerBuilder auth) { - auth - .inMemoryAuthentication() - .withUser(PasswordEncodedUser.user()); - } - } - - def "README Sample works"() { - setup: "Sample Config is loaded" - loadConfig(SampleWebSecurityConfigurerAdapter) - when: - springSecurityFilterChain.doFilter(request,response,chain) - then: - response.getRedirectedUrl() == "http://localhost/login" - when: "fail to log in" - super.setup() - request.servletPath = "/login" - request.method = "POST" - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to login error page" - response.getRedirectedUrl() == "/login?error" - when: "login success" - super.setup() - request.servletPath = "/login" - request.method = "POST" - request.parameters.username = ["user"] as String[] - request.parameters.password = ["password"] as String[] - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to default succes page" - response.getRedirectedUrl() == "/" - } - - /** - * - * - * - * - * - * - * - * - * - * password-parameter="password" - * username-parameter="username" - * /> - * - * - * - * - * - * - * - * - * - * - * @author Rob Winch - */ - @EnableWebSecurity - public static class SampleWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - - @Override - public void configure(WebSecurity web) throws Exception { - web - .ignoring() - .antMatchers("/resources/**"); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .antMatchers("/signup","/about").permitAll() - .anyRequest().hasRole("USER") - .and() - .formLogin() - .loginPage("/login") - // set permitAll for all URLs associated with Form Login - .permitAll(); - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) { - auth - .inMemoryAuthentication() - .withUser(PasswordEncodedUser.user()) - .withUser(PasswordEncodedUser.admin()); - } - } - - def "README Multi http Sample works"() { - setup: - loadConfig(SampleMultiHttpSecurityConfig) - when: - springSecurityFilterChain.doFilter(request,response,chain) - then: - response.getRedirectedUrl() == "http://localhost/login" - when: "fail to log in" - super.setup() - request.servletPath = "/login" - request.method = "POST" - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to login error page" - response.getRedirectedUrl() == "/login?error" - when: "login success" - super.setup() - request.servletPath = "/login" - request.method = "POST" - request.parameters.username = ["user"] as String[] - request.parameters.password = ["password"] as String[] - springSecurityFilterChain.doFilter(request,response,chain) - then: "sent to default succes page" - response.getRedirectedUrl() == "/" - - when: "request protected API URL" - super.setup() - request.servletPath = "/api/admin/test" - springSecurityFilterChain.doFilter(request,response,chain) - then: "get 401" - response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED - - when: "request API for admins with user" - super.setup() - request.servletPath = "/api/admin/test" - request.addHeader("Authorization", "Basic " + "user:password".bytes.encodeBase64().toString()) - springSecurityFilterChain.doFilter(request,response,chain) - then: "get 403" - response.getStatus() == HttpServletResponse.SC_FORBIDDEN - - when: "request API for admins with admin" - super.setup() - request.servletPath = "/api/admin/test" - request.addHeader("Authorization", "Basic " + "admin:password".bytes.encodeBase64().toString()) - springSecurityFilterChain.doFilter(request,response,chain) - then: "get 200" - response.getStatus() == HttpServletResponse.SC_OK - } - - - /** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * password-parameter="password" - * username-parameter="username" - * /> - * - * - * - * - * - * - * - * - * - * - * @author Rob Winch - */ - @EnableWebSecurity - public static class SampleMultiHttpSecurityConfig { - @Autowired - protected void configure(AuthenticationManagerBuilder auth) { - auth - .inMemoryAuthentication() - .withUser(PasswordEncodedUser.user()) - .withUser(PasswordEncodedUser.admin()); - } - - @Configuration - @Order(1) - public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { - protected void configure(HttpSecurity http) throws Exception { - http - .antMatcher("/api/**") - .authorizeRequests() - .antMatchers("/api/admin/**").hasRole("ADMIN") - .antMatchers("/api/**").hasRole("USER") - .and() - .httpBasic(); - } - } - - @Configuration - public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { - @Override - public void configure(WebSecurity web) throws Exception { - web - .ignoring() - .antMatchers("/resources/**"); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .antMatchers("/signup","/about").permitAll() - .anyRequest().hasRole("USER") - .and() - .formLogin() - .loginPage("/login") - .permitAll(); - } - } - } -} \ No newline at end of file diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.java new file mode 100644 index 0000000000..cd09cdf9c2 --- /dev/null +++ b/config/src/test/java/org/springframework/security/config/annotation/web/SampleWebSecurityConfigurerAdapterTests.java @@ -0,0 +1,389 @@ +/* + * Copyright 2002-2018 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.config.annotation.web; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.mock.web.MockFilterChain; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.test.SpringTestRule; +import org.springframework.security.core.userdetails.PasswordEncodedUser; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.security.web.csrf.DefaultCsrfToken; +import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository; + +import javax.servlet.http.HttpServletResponse; +import java.util.Base64; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Demonstrate the samples. + * + * @author Rob Winch + * @author Joe Grandja + */ +public class SampleWebSecurityConfigurerAdapterTests { + @Rule + public final SpringTestRule spring = new SpringTestRule(); + + @Autowired + private FilterChainProxy springSecurityFilterChain; + + private MockHttpServletRequest request; + private MockHttpServletResponse response; + private MockFilterChain chain; + + @Before + public void setup() { + this.request = new MockHttpServletRequest("GET", ""); + this.response = new MockHttpServletResponse(); + this.chain = new MockFilterChain(); + + CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "CSRF-TOKEN-TEST"); + new HttpSessionCsrfTokenRepository().saveToken(csrfToken, this.request, this.response); + this.request.setParameter(csrfToken.getParameterName(), csrfToken.getToken()); + } + + @Test + public void helloWorldSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception { + this.spring.register(HelloWorldWebSecurityConfigurerAdapter.class).autowire(); + + this.request.addHeader("Accept", "text/html"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login"); + } + + @Test + public void helloWorldSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception { + this.spring.register(HelloWorldWebSecurityConfigurerAdapter.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.request.addHeader("Accept", "text/html"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error"); + } + + @Test + public void helloWorldSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception { + this.spring.register(HelloWorldWebSecurityConfigurerAdapter.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.request.addHeader("Accept", "text/html"); + this.request.addParameter("username", "user"); + this.request.addParameter("password", "password"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/"); + } + + /** + * + * + * + * + * + * login-processing-url="/login" + * password-parameter="password" + * username-parameter="username" + * /> + * + * + * + * + * + * + * + * + * + * @author Rob Winch + */ + @EnableWebSecurity + public static class HelloWorldWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser(PasswordEncodedUser.user()); + } + } + + + @Test + public void readmeSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception { + this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire(); + + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login"); + } + + @Test + public void readmeSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception { + this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error"); + } + + @Test + public void readmeSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception { + this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.request.addParameter("username", "user"); + this.request.addParameter("password", "password"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/"); + } + + /** + * + * + * + * + * + * + * + * + * + * password-parameter="password" + * username-parameter="username" + * /> + * + * + * + * + * + * + * + * + * + * + * @author Rob Winch + */ + @EnableWebSecurity + public static class SampleWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + @Override + public void configure(WebSecurity web) throws Exception { + web + .ignoring() + .antMatchers("/resources/**"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/signup", "/about").permitAll() + .anyRequest().hasRole("USER") + .and() + .formLogin() + .loginPage("/login") + // set permitAll for all URLs associated with Form Login + .permitAll(); + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser(PasswordEncodedUser.user()) + .withUser(PasswordEncodedUser.admin()); + } + } + + + @Test + public void multiHttpSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login"); + } + + @Test + public void multiHttpSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error"); + } + + @Test + public void multiHttpSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.request.setServletPath("/login"); + this.request.setMethod("POST"); + this.request.addParameter("username", "user"); + this.request.addParameter("password", "password"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getRedirectedUrl()).isEqualTo("/"); + } + + @Test + public void multiHttpSampleWhenRequestProtectedResourceThenStatusUnauthorized() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.request.setServletPath("/api/admin/test"); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED); + } + + @Test + public void multiHttpSampleWhenRequestAdminResourceWithRegularUserThenStatusForbidden() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.request.setServletPath("/api/admin/test"); + this.request.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes())); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN); + } + + @Test + public void multiHttpSampleWhenRequestAdminResourceWithAdminUserThenStatusOk() throws Exception { + this.spring.register(SampleMultiHttpSecurityConfig.class).autowire(); + + this.request.setServletPath("/api/admin/test"); + this.request.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("admin:password".getBytes())); + this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain); + + assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK); + } + + /** + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * password-parameter="password" + * username-parameter="username" + * /> + * + * + * + * + * + * + * + * + * + * + * @author Rob Winch + */ + @EnableWebSecurity + public static class SampleMultiHttpSecurityConfig { + @Autowired + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser(PasswordEncodedUser.user()) + .withUser(PasswordEncodedUser.admin()); + } + + @Configuration + @Order(1) + public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/api/**") + .authorizeRequests() + .antMatchers("/api/admin/**").hasRole("ADMIN") + .antMatchers("/api/**").hasRole("USER") + .and() + .httpBasic(); + } + } + + @Configuration + public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + @Override + public void configure(WebSecurity web) throws Exception { + web + .ignoring() + .antMatchers("/resources/**"); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/signup", "/about").permitAll() + .anyRequest().hasRole("USER") + .and() + .formLogin() + .loginPage("/login") + .permitAll(); + } + } + } +}