View Javadoc
1   /*
2    * Licensed under the GPL License. You may not use this file except in compliance with the License.
3    * You may obtain a copy of the License at
4    *
5    *   https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
6    *
7    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
8    * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
9    * PURPOSE.
10   */
11  package psiprobe;
12  
13  import com.thoughtworks.xstream.XStream;
14  import com.thoughtworks.xstream.security.NoTypePermission;
15  import com.thoughtworks.xstream.security.NullPermission;
16  import com.thoughtworks.xstream.security.PrimitiveTypePermission;
17  
18  import java.util.ArrayList;
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.TreeMap;
22  
23  import org.springframework.context.annotation.Bean;
24  import org.springframework.context.annotation.Configuration;
25  import org.springframework.security.authentication.AuthenticationProvider;
26  import org.springframework.security.authentication.ProviderManager;
27  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
28  import org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper;
29  import org.springframework.security.web.DefaultSecurityFilterChain;
30  import org.springframework.security.web.FilterChainProxy;
31  import org.springframework.security.web.SecurityFilterChain;
32  import org.springframework.security.web.access.ExceptionTranslationFilter;
33  import org.springframework.security.web.access.intercept.AuthorizationFilter;
34  import org.springframework.security.web.access.intercept.RequestMatcherDelegatingAuthorizationManager;
35  import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
36  import org.springframework.security.web.authentication.logout.LogoutFilter;
37  import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
38  import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
39  import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService;
40  import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
41  import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
42  import org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever;
43  import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
44  import org.springframework.security.web.context.SecurityContextHolderFilter;
45  import org.springframework.security.web.context.SecurityContextRepository;
46  import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
47  
48  /**
49   * The Class ProbeSecurityConfig.
50   */
51  @Configuration
52  @EnableWebSecurity
53  public class ProbeSecurityConfig {
54  
55    /**
56     * Gets the filter chain proxy.
57     *
58     * @return the filter chain proxy
59     */
60    @Bean(name = "filterChainProxy")
61    public FilterChainProxy getFilterChainProxy() {
62      SecurityFilterChain chain =
63          new DefaultSecurityFilterChain(PathPatternRequestMatcher.withDefaults().matcher("/**"),
64              securityContextHolderFilter(securityContextRepository()),
65              getJ2eePreAuthenticatedProcessingFilter(), getLogoutFilter(),
66              getExceptionTranslationFilter(), getAuthorizationFilter());
67  
68      return new FilterChainProxy(chain);
69    }
70  
71    /**
72     * Gets the provider manager.
73     *
74     * @return the provider manager
75     */
76    @Bean(name = "authenticationManager")
77    public ProviderManager getProviderManager() {
78      List<AuthenticationProvider> providers = new ArrayList<>();
79      providers.add(getPreAuthenticatedAuthenticationProvider());
80  
81      return new ProviderManager(providers);
82    }
83  
84    /**
85     * Security context holder filter.
86     *
87     * @param repository the repository
88     * @return the security context holder filter
89     */
90    @Bean
91    public SecurityContextHolderFilter securityContextHolderFilter(
92        SecurityContextRepository repository) {
93      return new SecurityContextHolderFilter(repository);
94    }
95  
96    /**
97     * Security context repository.
98     *
99     * @return the security context repository
100    */
101   @Bean
102   public SecurityContextRepository securityContextRepository() {
103     return new HttpSessionSecurityContextRepository();
104   }
105 
106   /**
107    * Gets the pre authenticated authentication provider.
108    *
109    * @return the pre authenticated authentication provider
110    */
111   @Bean(name = "preAuthenticatedAuthenticationProvider")
112   public PreAuthenticatedAuthenticationProvider getPreAuthenticatedAuthenticationProvider() {
113     PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
114 
115     provider.setPreAuthenticatedUserDetailsService(
116         getPreAuthenticatedGrantedAuthoritiesUserDetailsService());
117 
118     return provider;
119   }
120 
121   /**
122    * Gets the pre authenticated granted authorities user details service.
123    *
124    * @return the pre authenticated granted authorities user details service
125    */
126   @Bean(name = "preAuthenticatedGrantedAuthoritiesUserDetailsService")
127   public PreAuthenticatedGrantedAuthoritiesUserDetailsService getPreAuthenticatedGrantedAuthoritiesUserDetailsService() {
128     return new PreAuthenticatedGrantedAuthoritiesUserDetailsService();
129   }
130 
131   /**
132    * Gets the J2EE pre authenticated processing filter.
133    *
134    * @return the J2EE pre authenticated processing filter
135    */
136   @Bean(name = "j2eePreAuthenticatedProcessingFilter")
137   public J2eePreAuthenticatedProcessingFilter getJ2eePreAuthenticatedProcessingFilter() {
138     J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter();
139 
140     filter.setAuthenticationManager(getProviderManager());
141     filter.setAuthenticationDetailsSource(
142         getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource());
143 
144     return filter;
145   }
146 
147   /**
148    * Gets the HTTP 403 forbidden entry point.
149    *
150    * @return the HTTP 403 forbidden entry point
151    */
152   @Bean(name = "http403ForbiddenEntryPoint")
153   public Http403ForbiddenEntryPoint getHttp403ForbiddenEntryPoint() {
154     return new Http403ForbiddenEntryPoint();
155   }
156 
157   /**
158    * Gets the logout filter.
159    *
160    * @return the logout filter
161    */
162   @Bean(name = "logoutFilter")
163   public LogoutFilter getLogoutFilter() {
164     return new LogoutFilter("/", getSecurityContextLogoutHandler());
165   }
166 
167   /**
168    * Gets the security context logout handler.
169    *
170    * @return the security context logout handler
171    */
172   @Bean(name = "securityContextLogoutHandler")
173   public SecurityContextLogoutHandler getSecurityContextLogoutHandler() {
174     return new SecurityContextLogoutHandler();
175   }
176 
177   /**
178    * Gets the J2EE based pre authenticated web authentication details source.
179    *
180    * @return the J2EE based pre authenticated web authentication details source
181    */
182   @Bean(name = "j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource")
183   public J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource() {
184     J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource source =
185         new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
186 
187     source.setMappableRolesRetriever(getWebXmlMappableAttributesRetriever());
188     source.setUserRoles2GrantedAuthoritiesMapper(getSimpleAttributes2GrantedAuthoritiesMapper());
189 
190     return source;
191   }
192 
193   /**
194    * Gets the simple attributes 2 granted authorities mapper.
195    *
196    * @return the simple attributes 2 granted authorities mapper
197    */
198   @Bean(name = "simpleAttributes2GrantedAuthoritiesMapper")
199   public SimpleAttributes2GrantedAuthoritiesMapper getSimpleAttributes2GrantedAuthoritiesMapper() {
200     SimpleAttributes2GrantedAuthoritiesMapper mapper =
201         new SimpleAttributes2GrantedAuthoritiesMapper();
202 
203     mapper.setConvertAttributeToUpperCase(true);
204 
205     return mapper;
206   }
207 
208   /**
209    * Gets the web XML mappable attributes retriever.
210    *
211    * @return the web XML mappable attributes retriever
212    */
213   @Bean(name = "webXmlMappableAttributesRetriever")
214   public WebXmlMappableAttributesRetriever getWebXmlMappableAttributesRetriever() {
215     return new WebXmlMappableAttributesRetriever();
216   }
217 
218   /**
219    * Gets the exception translation filter.
220    *
221    * @return the exception translation filter
222    */
223   @Bean(name = "exceptionTranslationFilter")
224   public ExceptionTranslationFilter getExceptionTranslationFilter() {
225     return new ExceptionTranslationFilter(getHttp403ForbiddenEntryPoint());
226   }
227 
228   /**
229    * Gets the authorization filter.
230    *
231    * @return the authorization filter
232    */
233   @Bean(name = "authorizationFilter")
234   public AuthorizationFilter getAuthorizationFilter() {
235     return new AuthorizationFilter(getAuthorizationManager());
236   }
237 
238   /**
239    * Gets the authorization manager.
240    *
241    * @return the authorization manager
242    */
243   @Bean(name = "authorizationManager")
244   public RequestMatcherDelegatingAuthorizationManager getAuthorizationManager() {
245     PathPatternRequestMatcher.Builder matcher = PathPatternRequestMatcher.withDefaults();
246 
247     RequestMatcherDelegatingAuthorizationManager.Builder manager =
248         RequestMatcherDelegatingAuthorizationManager.builder();
249 
250     manager.requestMatchers(matcher.matcher("/adm/**")).hasAnyAuthority("ROLE_MANAGER",
251         "ROLE_MANAGER-GUI");
252 
253     manager.requestMatchers(matcher.matcher("/adm/restartvm.ajax"))
254         .hasAnyAuthority("ROLE_POWERUSERPLUS", "ROLE_MANAGER", "ROLE_MANAGER-GUI");
255 
256     manager.requestMatchers(matcher.matcher("/sql/**")).hasAnyAuthority("ROLE_POWERUSERPLUS",
257         "ROLE_MANAGER", "ROLE_MANAGER-GUI");
258 
259     manager.requestMatchers(matcher.matcher("/app/**")).hasAnyAuthority("ROLE_POWERUSER",
260         "ROLE_POWERUSERPLUS", "ROLE_MANAGER", "ROLE_MANAGER-GUI");
261 
262     manager.anyRequest().hasAnyAuthority("ROLE_PROBEUSER", "ROLE_POWERUSER", "ROLE_POWERUSERPLUS",
263         "ROLE_MANAGER", "ROLE_MANAGER-GUI");
264 
265     return manager.build();
266   }
267 
268   /**
269    * Gets the XStream.
270    *
271    * @return the XStream
272    */
273   @Bean(name = "xstream")
274   public XStream getXstream() {
275     XStream xstream = new XStream();
276 
277     // Clear out existing permissions and start a whitelist.
278     xstream.addPermission(NoTypePermission.NONE);
279 
280     // Allow some basics.
281     xstream.addPermission(NullPermission.NULL);
282     xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
283     xstream.allowTypeHierarchy(Collection.class);
284     xstream.allowTypeHierarchy(String.class);
285     xstream.allowTypeHierarchy(TreeMap.class);
286 
287     xstream.allowTypesByWildcard(new String[] {"org.jfree.data.xy.**", "psiprobe.controllers.**",
288         "psiprobe.model.**", "psiprobe.model.stats.**"});
289 
290     return xstream;
291   }
292 
293 }