SEC-3094: Add @WithAnonymousUser & anonymous() MockMvcRequestPostProcessor
This commit is contained in:
parent
6b05b298ff
commit
35393098f8
|
@ -137,6 +137,37 @@ For example, the following would run every test with a user with the username "a
|
|||
public class WithMockUserTests {
|
||||
----
|
||||
|
||||
|
||||
[[test-method-withanonymoususer]]
|
||||
=== @WithAnonymousUser
|
||||
|
||||
Using `@WithAnonymousUser` allows running as an anonymous user.
|
||||
This is especially convenient when you wish to run most of your tests with a specific user, but want to run a few tests as an anonymous user.
|
||||
For example, the following will run withMockUser1 and withMockUser2 using <<test-method-withmockuser,@WithMockUser>> and anonymous as an anonymous user.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@WithMockUser
|
||||
public class WithUserClassLevelAuthenticationTests {
|
||||
|
||||
@Test
|
||||
public void withMockUser1() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withMockUser2() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithAnonymousUser
|
||||
public void anonymous() throws Exception {
|
||||
// override default to run as anonymous user
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
[[test-method-withuserdetails]]
|
||||
=== @WithUserDetails
|
||||
|
||||
|
@ -409,6 +440,16 @@ mvc
|
|||
.perform(get("/").with(user(userDetails)))
|
||||
----
|
||||
|
||||
You can run as anonymous user using the following:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
mvc
|
||||
.perform(get("/").with(anonymous()))
|
||||
----
|
||||
|
||||
This is especially useful if you are running with a default user and wish to execute a few requests as an anonymous user.
|
||||
|
||||
If you want a custom `Authentication` (which does not need to exist) you can do so using the following:
|
||||
|
||||
[source,java]
|
||||
|
|
|
@ -373,6 +373,7 @@ This will give you access to the entire project history (including all releases
|
|||
** <<test-method-meta-annotations,Test Meta Annotations>>
|
||||
** <<method-security-meta-annotations,Method Security Meta Annotations>>
|
||||
* <<el-access-web-path-variables,Path Variables in Web Security Expressions>>
|
||||
* <<test-method-withanonymoususer,@WithAnonymousUser>>
|
||||
|
||||
=== What's new in Spring Security 4.0
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.test.context.support;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
|
||||
/**
|
||||
* When used with {@link WithSecurityContextTestExecutionListener} this
|
||||
* annotation can be added to a test method to emulate running with an anonymous
|
||||
* user. The {@link SecurityContext} that is used will contain an
|
||||
* {@link AnonymousAuthenticationToken}. This is useful when a user wants to run
|
||||
* a majority of tests as a specific user and wishes to override a few methods
|
||||
* to be anonymous. For example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* @WithMockUser
|
||||
* public class SecurityTests {
|
||||
* @Test
|
||||
* @WithAnonymousUser
|
||||
* public void runAsAnonymous() {
|
||||
* // ... run as an anonymous user ...
|
||||
* }
|
||||
*
|
||||
* // ... lots of tests ran with a default user ...
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.1
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
@WithSecurityContext(factory = WithAnonymousUserSecurityContextFactory.class)
|
||||
public @interface WithAnonymousUser {
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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.test.context.support;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* A {@link WithAnonymousUserSecurityContextFactory} that runs with an {@link AnonymousAuthenticationToken}.
|
||||
* .
|
||||
*
|
||||
* @see WithUserDetails
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.1
|
||||
*/
|
||||
|
||||
final class WithAnonymousUserSecurityContextFactory implements
|
||||
WithSecurityContextFactory<WithAnonymousUser> {
|
||||
|
||||
public SecurityContext createSecurityContext(WithAnonymousUser withUser) {
|
||||
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
|
||||
Authentication authentication = new AnonymousAuthenticationToken("key", "anonymous", authorities);
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
context.setAuthentication(authentication);
|
||||
return context;
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ import org.springframework.core.io.Resource;
|
|||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
|
@ -217,6 +218,38 @@ public final class SecurityMockMvcRequestPostProcessors {
|
|||
return new AuthenticationRequestPostProcessor(authentication);
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish a {@link SecurityContext} that uses an
|
||||
* {@link AnonymousAuthenticationToken}. This is useful when a user wants to
|
||||
* run a majority of tests as a specific user and wishes to override a few
|
||||
* methods to be anonymous. For example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* public class SecurityTests {
|
||||
* @Before
|
||||
* public void setup() {
|
||||
* mockMvc = MockMvcBuilders
|
||||
* .webAppContextSetup(context)
|
||||
* .defaultRequest(get("/").with(user("user")))
|
||||
* .build();
|
||||
* }
|
||||
*
|
||||
* @Test
|
||||
* public void anonymous() {
|
||||
* mockMvc.perform(get("anonymous").with(anonymous()));
|
||||
* }
|
||||
* // ... lots of tests ran with a default user ...
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @return the {@link RequestPostProcessor} to use
|
||||
*/
|
||||
public static RequestPostProcessor anonymous() {
|
||||
return new AnonymousRequestPostProcessor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish the specified {@link SecurityContext} to be used.
|
||||
*
|
||||
|
@ -761,6 +794,17 @@ public final class SecurityMockMvcRequestPostProcessors {
|
|||
}
|
||||
}
|
||||
|
||||
private static class AnonymousRequestPostProcessor extends SecurityContextRequestPostProcessorSupport implements RequestPostProcessor {
|
||||
private AuthenticationRequestPostProcessor delegate = new AuthenticationRequestPostProcessor(new AnonymousAuthenticationToken("key", "anonymous", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS")));
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.test.web.servlet.request.RequestPostProcessor#postProcessRequest(org.springframework.mock.web.MockHttpServletRequest)
|
||||
*/
|
||||
public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
|
||||
return delegate.postProcessRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
private static class HttpBasicRequestPostProcessor implements RequestPostProcessor {
|
||||
private String headerValue;
|
||||
|
||||
|
|
|
@ -18,20 +18,17 @@ package org.springframework.security.test.web.servlet.showcase.secured;
|
|||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.*;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
@ -48,9 +45,6 @@ public class DefaultfSecurityRequestsTests {
|
|||
@Autowired
|
||||
private WebApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Filter springSecurityFilterChain;
|
||||
|
||||
private MockMvc mvc;
|
||||
|
||||
@Before
|
||||
|
@ -78,6 +72,15 @@ public class DefaultfSecurityRequestsTests {
|
|||
.andExpect(authenticated().withUsername("user"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestProtectedUrlWithAnonymous() throws Exception {
|
||||
mvc.perform(get("/admin").with(anonymous()))
|
||||
// Ensure we got past Security
|
||||
.andExpect(status().isUnauthorized())
|
||||
// Ensure it appears we are authenticated with user
|
||||
.andExpect(unauthenticated());
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
static class Config extends WebSecurityConfigurerAdapter {
|
||||
|
@ -90,7 +93,7 @@ public class DefaultfSecurityRequestsTests {
|
|||
.antMatchers("/admin/**").hasRole("ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin();
|
||||
.httpBasic();
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
|
|
|
@ -15,15 +15,21 @@
|
|||
*/
|
||||
package org.springframework.security.test.web.servlet.showcase.secured;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.test.context.support.WithAnonymousUser;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
@ -33,11 +39,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = WithUserClassLevelAuthenticationTests.Config.class)
|
||||
@WebAppConfiguration
|
||||
|
@ -72,6 +73,16 @@ public class WithUserClassLevelAuthenticationTests {
|
|||
.andExpect(authenticated().withUsername("user").withRoles("ADMIN"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithAnonymousUser
|
||||
public void requestProtectedUrlWithAnonymous() throws Exception {
|
||||
mvc.perform(get("/"))
|
||||
// Ensure did not get past security
|
||||
.andExpect(status().isUnauthorized())
|
||||
// Ensure not authenticated
|
||||
.andExpect(unauthenticated());
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
@EnableWebMvc
|
||||
static class Config extends WebSecurityConfigurerAdapter {
|
||||
|
@ -84,7 +95,7 @@ public class WithUserClassLevelAuthenticationTests {
|
|||
.antMatchers("/admin/**").hasRole("ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin();
|
||||
.httpBasic();
|
||||
}
|
||||
// @formatter:on
|
||||
|
||||
|
|
Loading…
Reference in New Issue