1
0
mirror of synced 2026-08-05 09:47:05 +00:00

SEC-3094: Add @WithAnonymousUser & anonymous() MockMvcRequestPostProcessor

This commit is contained in:
Rob Winch
2015-08-27 15:17:44 -05:00
parent 6b05b298ff
commit 35393098f8
7 changed files with 226 additions and 18 deletions
@@ -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>
* &#064;WithMockUser
* public class SecurityTests {
* &#064;Test
* &#064;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 {
* &#064;Before
* public void setup() {
* mockMvc = MockMvcBuilders
* .webAppContextSetup(context)
* .defaultRequest(get("/").with(user("user")))
* .build();
* }
*
* &#064;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;