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.LinkedHashMap;
21  import java.util.List;
22  import java.util.TreeMap;
23  
24  import org.springframework.context.annotation.Bean;
25  import org.springframework.context.annotation.Configuration;
26  import org.springframework.security.access.AccessDecisionVoter;
27  import org.springframework.security.access.ConfigAttribute;
28  import org.springframework.security.access.SecurityConfig;
29  import org.springframework.security.access.vote.AffirmativeBased;
30  import org.springframework.security.access.vote.RoleVoter;
31  import org.springframework.security.authentication.AuthenticationProvider;
32  import org.springframework.security.authentication.ProviderManager;
33  import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
34  import org.springframework.security.core.authority.mapping.SimpleAttributes2GrantedAuthoritiesMapper;
35  import org.springframework.security.web.DefaultSecurityFilterChain;
36  import org.springframework.security.web.FilterChainProxy;
37  import org.springframework.security.web.SecurityFilterChain;
38  import org.springframework.security.web.access.ExceptionTranslationFilter;
39  import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource;
40  import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
41  import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
42  import org.springframework.security.web.authentication.logout.LogoutFilter;
43  import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
44  import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
45  import org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesUserDetailsService;
46  import org.springframework.security.web.authentication.preauth.j2ee.J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource;
47  import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
48  import org.springframework.security.web.authentication.preauth.j2ee.WebXmlMappableAttributesRetriever;
49  import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
50  import org.springframework.security.web.context.SecurityContextHolderFilter;
51  import org.springframework.security.web.context.SecurityContextRepository;
52  import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
53  import org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter;
54  import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
55  import org.springframework.security.web.util.matcher.RequestMatcher;
56  
57  /**
58   * The Class ProbeSecurityConfig.
59   */
60  @Configuration
61  @EnableWebSecurity
62  public class ProbeSecurityConfig {
63  
64    /**
65     * Gets the filter chain proxy.
66     *
67     * @return the filter chain proxy
68     */
69    @Bean(name = "filterChainProxy")
70    public FilterChainProxy getFilterChainProxy() {
71      SecurityFilterChain chain = new DefaultSecurityFilterChain(new AntPathRequestMatcher("/**"),
72          securityContextHolderFilter(securityContextRepository()),
73          getJ2eePreAuthenticatedProcessingFilter(), getLogoutFilter(),
74          getExceptionTranslationFilter(), getFilterSecurityInterceptor());
75      return new FilterChainProxy(chain);
76    }
77  
78    /**
79     * Gets the provider manager.
80     *
81     * @return the provider manager
82     */
83    @Bean(name = "authenticationManager")
84    public ProviderManager getProviderManager() {
85      List<AuthenticationProvider> providers = new ArrayList<>();
86      providers.add(getPreAuthenticatedAuthenticationProvider());
87      return new ProviderManager(providers);
88    }
89  
90  
91    /**
92     * Security context holder filter.
93     *
94     * @param repository the repository
95     * @return the security context holder filter
96     */
97    @Bean
98    public SecurityContextHolderFilter securityContextHolderFilter(
99        SecurityContextRepository repository) {
100     return new SecurityContextHolderFilter(repository);
101   }
102 
103   /**
104    * Security context repository.
105    *
106    * @return the security context repository
107    */
108   @Bean
109   public SecurityContextRepository securityContextRepository() {
110     return new HttpSessionSecurityContextRepository();
111   }
112 
113   /**
114    * Gets the pre authenticated authentication provider.
115    *
116    * @return the pre authenticated authentication provider
117    */
118   @Bean(name = "preAuthenticatedAuthenticationProvider")
119   public PreAuthenticatedAuthenticationProvider getPreAuthenticatedAuthenticationProvider() {
120     PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
121     provider.setPreAuthenticatedUserDetailsService(
122         getPreAuthenticatedGrantedAuthoritiesUserDetailsService());
123     return provider;
124   }
125 
126   /**
127    * Gets the pre authenticated granted authorities user details service.
128    *
129    * @return the pre authenticated granted authorities user details service
130    */
131   @Bean(name = "preAuthenticatedGrantedAuthoritiesUserDetailsService")
132   public PreAuthenticatedGrantedAuthoritiesUserDetailsService getPreAuthenticatedGrantedAuthoritiesUserDetailsService() {
133     return new PreAuthenticatedGrantedAuthoritiesUserDetailsService();
134   }
135 
136   /**
137    * Gets the j 2 ee pre authenticated processing filter.
138    *
139    * @return the j 2 ee pre authenticated processing filter
140    */
141   @Bean(name = "j2eePreAuthenticatedProcessingFilter")
142   public J2eePreAuthenticatedProcessingFilter getJ2eePreAuthenticatedProcessingFilter() {
143     J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter();
144     filter.setAuthenticationManager(getProviderManager());
145     filter.setAuthenticationDetailsSource(
146         getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource());
147     return filter;
148   }
149 
150   /**
151    * Gets the http 403 forbidden entry point.
152    *
153    * @return the http 403 forbidden entry point
154    */
155   @Bean(name = "http403ForbiddenEntryPoint")
156   public Http403ForbiddenEntryPoint getHttp403ForbiddenEntryPoint() {
157     return new Http403ForbiddenEntryPoint();
158   }
159 
160   /**
161    * Gets the logout filter.
162    *
163    * @return the logout filter
164    */
165   @Bean(name = "logoutFilter")
166   public LogoutFilter getLogoutFilter() {
167     return new LogoutFilter("/", getSecurityContextLogoutHandler());
168   }
169 
170   /**
171    * Gets the security context logout handler.
172    *
173    * @return the security context logout handler
174    */
175   @Bean(name = "securityContextLogoutHandler")
176   public SecurityContextLogoutHandler getSecurityContextLogoutHandler() {
177     return new SecurityContextLogoutHandler();
178   }
179 
180   /**
181    * Gets the j 2 ee based pre authenticated web authentication details source.
182    *
183    * @return the j 2 ee based pre authenticated web authentication details source
184    */
185   @Bean(name = "j2eeBasedPreAuthenticatedWebAuthenticationDetailsSource")
186   public J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource getJ2eeBasedPreAuthenticatedWebAuthenticationDetailsSource() {
187     J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource source =
188         new J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource();
189     source.setMappableRolesRetriever(getWebXmlMappableAttributesRetriever());
190     source.setUserRoles2GrantedAuthoritiesMapper(getSimpleAttributes2GrantedAuthoritiesMapper());
191     return source;
192   }
193 
194   /**
195    * Gets the simple attributes 2 granted authorities mapper.
196    *
197    * @return the simple attributes 2 granted authorities mapper
198    */
199   @Bean(name = "simpleAttributes2GrantedAuthoritiesMapper")
200   public SimpleAttributes2GrantedAuthoritiesMapper getSimpleAttributes2GrantedAuthoritiesMapper() {
201     SimpleAttributes2GrantedAuthoritiesMapper mapper =
202         new SimpleAttributes2GrantedAuthoritiesMapper();
203     mapper.setConvertAttributeToUpperCase(true);
204     return mapper;
205   }
206 
207   /**
208    * Gets the web xml mappable attributes retriever.
209    *
210    * @return the web xml mappable attributes retriever
211    */
212   @Bean(name = "webXmlMappableAttributesRetriever")
213   public WebXmlMappableAttributesRetriever getWebXmlMappableAttributesRetriever() {
214     return new WebXmlMappableAttributesRetriever();
215   }
216 
217   /**
218    * Gets the exception translation filter.
219    *
220    * @return the exception translation filter
221    */
222   @Bean(name = "exceptionTranslationFilter")
223   public ExceptionTranslationFilter getExceptionTranslationFilter() {
224     return new ExceptionTranslationFilter(getHttp403ForbiddenEntryPoint());
225   }
226 
227   /**
228    * Gets the affirmative based.
229    *
230    * @return the affirmative based
231    */
232   @Bean(name = "affirmativeBased")
233   public AffirmativeBased getAffirmativeBased() {
234     List<AccessDecisionVoter<? extends Object>> decisionVoters = new ArrayList<>();
235     decisionVoters.add(getRoleVoter());
236 
237     AffirmativeBased based = new AffirmativeBased(decisionVoters);
238     based.setAllowIfAllAbstainDecisions(false);
239     return based;
240   }
241 
242   /**
243    * Gets the filter security interceptor.
244    *
245    * @return the filter security interceptor
246    */
247   @Bean(name = "filterSecurityInterceptor")
248   public FilterSecurityInterceptor getFilterSecurityInterceptor() {
249     FilterSecurityInterceptor interceptor = new FilterSecurityInterceptor();
250     interceptor.setAuthenticationManager(getProviderManager());
251     interceptor.setAccessDecisionManager(getAffirmativeBased());
252 
253     LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<>();
254     requestMap.put(new AntPathRequestMatcher("/adm/**"),
255         SecurityConfig.createListFromCommaDelimitedString("ROLE_MANAGER,ROLE_MANAGER-GUI"));
256     requestMap.put(new AntPathRequestMatcher("/adm/restartvm.ajax"), SecurityConfig
257         .createListFromCommaDelimitedString("ROLE_POWERUSERPLUS,ROLE_MANAGER,ROLE_MANAGER-GUI"));
258     requestMap.put(new AntPathRequestMatcher("/sql/**"), SecurityConfig
259         .createListFromCommaDelimitedString("ROLE_POWERUSERPLUS,ROLE_MANAGER,ROLE_MANAGER-GUI"));
260     requestMap.put(new AntPathRequestMatcher("/app/**"),
261         SecurityConfig.createListFromCommaDelimitedString(
262             "ROLE_POWERUSER,ROLE_POWERUSERPLUS,ROLE_MANAGER,ROLE_MANAGER-GUI"));
263     requestMap.put(new AntPathRequestMatcher("/**"),
264         SecurityConfig.createListFromCommaDelimitedString(
265             "ROLE_PROBEUSER,ROLE_POWERUSER,ROLE_POWERUSERPLUS,ROLE_MANAGER,ROLE_MANAGER-GUI"));
266 
267     interceptor
268         .setSecurityMetadataSource(new DefaultFilterInvocationSecurityMetadataSource(requestMap));
269     return interceptor;
270   }
271 
272   /**
273    * Gets the role voter.
274    *
275    * @return the role voter
276    */
277   @Bean(name = "roleVoter")
278   public RoleVoter getRoleVoter() {
279     return new RoleVoter();
280   }
281 
282   /**
283    * Gets the security context holder aware request filter.
284    *
285    * @return the security context holder aware request filter
286    */
287   @Bean(name = "securityContextHolderAwareRequestFilter")
288   public SecurityContextHolderAwareRequestFilter getSecurityContextHolderAwareRequestFilter() {
289     return new SecurityContextHolderAwareRequestFilter();
290   }
291 
292   /**
293    * Gets the http session request cache.
294    *
295    * @return the http session request cache
296    */
297   @Bean(name = "httpSessionRequestCache")
298   public HttpSessionRequestCache getHttpSessionRequestCache() {
299     HttpSessionRequestCache cache = new HttpSessionRequestCache();
300     cache.setCreateSessionAllowed(false);
301     return cache;
302   }
303 
304   /**
305    * Gets the xstream.
306    *
307    * @return the xstream
308    */
309   @Bean(name = "xstream")
310   public XStream getXstream() {
311     XStream xstream = new XStream();
312     // clear out existing permissions and start a whitelist
313     xstream.addPermission(NoTypePermission.NONE);
314     // allow some basics
315     xstream.addPermission(NullPermission.NULL);
316     xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
317     xstream.allowTypeHierarchy(Collection.class);
318     xstream.allowTypeHierarchy(String.class);
319     xstream.allowTypeHierarchy(TreeMap.class);
320     xstream.allowTypesByWildcard(new String[] {"org.jfree.data.xy.**", "psiprobe.controllers.**",
321         "psiprobe.model.**", "psiprobe.model.stats.**"});
322     return xstream;
323   }
324 
325 }