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