View Javadoc
1   /**
2    * Copyright 2013 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   *
15   */
16  package org.kuali.student.security.spring;
17  
18  import org.springframework.mock.web.MockHttpServletRequest;
19  import org.springframework.mock.web.MockHttpServletResponse;
20  import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
21  import org.springframework.security.core.Authentication;
22  import org.springframework.security.core.GrantedAuthority;
23  import org.springframework.security.core.authority.SimpleGrantedAuthority;
24  import org.springframework.security.core.context.SecurityContext;
25  import org.springframework.security.core.context.SecurityContextHolder;
26  import org.springframework.security.web.context.HttpRequestResponseHolder;
27  import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
28  import org.springframework.security.web.context.SecurityContextRepository;
29  import org.springframework.test.web.servlet.request.RequestPostProcessor;
30  import org.springframework.util.Assert;
31  
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpServletResponse;
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  /**
38   * Uses a {@link RequestPostProcessor} to add request-building methods for establishing
39   * a security context for Spring Security. Found from samples at:
40   * https://github.com/spring-projects/spring-test-mvc/blob/master/src/test/java/org/springframework/test/web/server/samples/context/SecurityRequestPostProcessors.java
41   *
42   * @author Kuali Student Team
43   */
44  public final class SecurityRequestPostProcessors {
45  
46  	/**
47  	 * Establish a security context for a user with the specified username. All
48  	 * details are declarative and do not require that the user actually exists.
49  	 * This means that the authorities or roles need to be specified too.
50  	 */
51  	public static UserRequestPostProcessor user(String username) {
52  		return new UserRequestPostProcessor(username);
53  	}
54  
55  	/** Support class for {@link RequestPostProcessor}'s that establish a Spring Security context */
56  	private static abstract class SecurityContextRequestPostProcessorSupport {
57  
58  		private SecurityContextRepository repository = new HttpSessionSecurityContextRepository();
59  
60  		final void save(Authentication authentication, HttpServletRequest request) {
61  			SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
62  			securityContext.setAuthentication(authentication);
63  			save(securityContext, request);
64  		}
65  
66  		final void save(SecurityContext securityContext, HttpServletRequest request) {
67  			HttpServletResponse response = new MockHttpServletResponse();
68  
69  			HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(request, response);
70  			this.repository.loadContext(requestResponseHolder);
71  
72  			request = requestResponseHolder.getRequest();
73  			response = requestResponseHolder.getResponse();
74  
75  			this.repository.saveContext(securityContext, request, response);
76  		}
77  	}
78  
79  	public final static class UserRequestPostProcessor
80  			extends SecurityContextRequestPostProcessorSupport implements RequestPostProcessor {
81  
82  		private final String username;
83  
84  		private static final String ROLE_PREFIX = "ROLE_";
85  
86  		private List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
87  
88  		private UserRequestPostProcessor(String username) {
89  			Assert.notNull(username, "username cannot be null");
90  			this.username = username;
91  		}
92  
93  		/**
94  		 * Specify the roles of the user to authenticate as.
95  		 */
96  		public UserRequestPostProcessor roles(String... roles) {
97  			List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(roles.length);
98  			for(String role : roles) {
99  				if(role.startsWith(ROLE_PREFIX)) {
100 					authorities.add(new SimpleGrantedAuthority(role));
101 				} else {
102 					authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + role));
103 				}
104 			}
105             this.authorities = authorities;
106 			return this;
107 		}
108 
109 		public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) {
110 			UsernamePasswordAuthenticationToken authentication =
111 					new UsernamePasswordAuthenticationToken(this.username, null, this.authorities);
112 			save(authentication,request);
113 			return request;
114 		}
115 	}
116 
117 	private SecurityRequestPostProcessors() {}
118 }