View Javadoc
1   /*
2    * Copyright (c) 2002-2022, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.web.system;
35  
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  import javax.servlet.http.HttpServletRequest;
41  
42  import org.apache.commons.lang3.StringUtils;
43  import org.apache.commons.text.StringEscapeUtils;
44  
45  import fr.paris.lutece.portal.business.securityheader.SecurityHeader;
46  import fr.paris.lutece.portal.business.securityheader.SecurityHeaderHome;
47  import fr.paris.lutece.portal.business.securityheader.SecurityHeaderType;
48  import fr.paris.lutece.portal.service.admin.AccessDeniedException;
49  import fr.paris.lutece.portal.service.message.AdminMessage;
50  import fr.paris.lutece.portal.service.message.AdminMessageService;
51  import fr.paris.lutece.portal.service.security.SecurityTokenService;
52  import fr.paris.lutece.portal.service.securityheader.SecurityHeaderService;
53  import fr.paris.lutece.portal.service.spring.SpringContextService;
54  import fr.paris.lutece.portal.service.template.AppTemplateService;
55  import fr.paris.lutece.portal.service.util.AppLogService;
56  import fr.paris.lutece.portal.util.mvc.admin.MVCAdminJspBean;
57  import fr.paris.lutece.util.ErrorMessage;
58  import fr.paris.lutece.util.ReferenceItem;
59  import fr.paris.lutece.util.ReferenceList;
60  import fr.paris.lutece.util.html.HtmlTemplate;
61  import fr.paris.lutece.util.http.SecurityUtil;
62  
63  /**
64   * This class provides the user interface to manage security headers features ( manage, create, modify, remove, activate/deactivate ).
65   */
66  public class SecurityHeaderJspBean extends MVCAdminJspBean
67  {
68      // Rights
69      public static final String RIGHT_SECURITY_HEADER_MANAGEMENT = "CORE_SECURITY_HEADER_MANAGEMENT";
70  
71      // Templates
72      private static final String TEMPLATE_CREATE_SECURITYHEADER = "admin/system/create_securityheader.html";
73      private static final String TEMPLATE_MODIFY_SECURITYHEADER = "admin/system/modify_securityheader.html";
74      
75      // Markers
76      private static final String MARK_SECURITY_HEADERS_LIST = "security_headers_list";
77      private static final String MARK_SECURITY_HEADER = "securityheader";
78      private static final String MARK_TYPES_LIST = "types_list";
79      private static final String MARK_TYPE_SELECTED = "selected_type";
80      private static final String MARK_PAGE_CATEGORY_LIST = "page_category_list";
81      private static final String MARK_PAGE_CATEGORY_SELECTED = "selected_pageCategory";
82      private static final String MARK_ERRORS = "errors";
83      
84      // Properties
85      private static final String PROPERTY_CREATE_SECURITYHEADER_PAGETITLE = "portal.securityheader.create_securityheader.pageTitle";
86      private static final String PROPERTY_MODIFY_SECURITYHEADER_PAGETITLE = "portal.securityheader.modify_securityheader.pageTitle";   
87      private static final String MESSAGE_ACTIVE_HEADER_NOT_EDITABLE = "portal.securityheader.message.activeHeaderNotEditable";
88      private static final String MESSAGE_CONFIRM_REMOVE = "portal.securityheader.message.confirmRemoveSecurityHeader";
89      private static final String MESSAGE_HEADER_ALREADY_EXIST = "portal.securityheader.message.securityHeadersAlreadyexists";    
90      private static final String MESSAGE_PAGE_CATEGORY_REQUIRED_WHEN_PAGE_IS_TYPE = "portal.securityheader.message.pageCategoryRequiredTypePage";
91      private static final String MESSAGE_TYPE_UNKNOWN = "portal.securityheader.message.typeUnknown";
92      private static final String MESSAGE_PAGE_CATEGORY_UNKNOWN = "portal.securityheader.message.pageCategoryUnknown";
93  
94   // Validations
95      private static final String VALIDATION_ATTRIBUTES_PREFIX = "portal.securityheader.model.entity.securityheader.attribute.";
96      
97      // Template Files path
98      private static final String TEMPLATE_MANAGE_SECURITY_HEADERS = "admin/system/manage_security_headers.html";
99      
100     // Parameters
101     private static final String PARAMETER_SECURITY_HEADER_ID = "id_securityheader";
102     private static final String PARAMETER_NAME = "name";
103     private static final String PARAMETER_VALUE = "value";
104     private static final String PARAMETER_DESCRIPTION = "description";
105     private static final String PARAMETER_TYPE = "type";
106     private static final String PARAMETER_PAGE_CATEGORY  = "pageCategory";
107     private static final String PARAMETER_ACTION = "action";
108     
109     // Jsp definition
110     public static final String JSP_MANAGE_SECURITY_HEADERS = "ManageSecurityHeaders.jsp";
111     public static final String JSP_REMOVE_SECURITY_HEADERS = "jsp/admin/system/DoRemoveSecurityHeader.jsp";
112     
113     // Actions
114     private static final String ACTION_ENABLE = "ENABLE";
115     private static final String ACTION_DISABLE = "DISABLE";
116   
117     private static final long serialVersionUID = 7010476999488231065L;
118     
119     /**
120      * Returns the page to manage security headers.
121      * 
122      * @param request
123      *            The HttpServletRequest
124      * @return The HTML code.
125      */
126     public String getManageSecurityHeaders( HttpServletRequest request )
127     {
128     	HashMap<String, Object> model = createModelForHeadersList( request );
129         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MANAGE_SECURITY_HEADERS, getLocale( ), model );
130 
131         return getAdminPage( template.getHtml( ) );
132     }
133     
134     /**
135      * 
136      * Creates the model used for displaying security headers list in manage security headers page.
137      * 
138      * @param request
139      *            The HttpServletRequest
140      * @return model map
141      */
142     private HashMap<String, Object> createModelForHeadersList( HttpServletRequest request )
143     {
144     	HashMap<String, Object> model = new HashMap<>( );
145         model.put( MARK_SECURITY_HEADERS_LIST, getSecurityHeaderService( ).findAllSorted( getLocale( ) ) );
146         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MANAGE_SECURITY_HEADERS ) );
147         
148         return model;
149     }
150     
151     /**
152      * Returns the security header creation page.
153      * 
154      * @param request
155      *            the http request
156      * @return the html code for the securityheader creation page
157      */
158     public String getCreateSecurityHeader( HttpServletRequest request )
159     {
160         setPageTitleProperty( PROPERTY_CREATE_SECURITYHEADER_PAGETITLE );
161         HashMap<String, Object> model = createModelForHeaderCreation( request );
162         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_CREATE_SECURITYHEADER, getLocale( ), model );
163 
164         return getAdminPage( template.getHtml( ) );
165     }
166     
167     /**
168      * 
169      * Creates the model used for adding a new security header.
170      * 
171      * @param request
172      *            The HttpServletRequest
173      * @return model map
174      */
175     private HashMap<String, Object> createModelForHeaderCreation( HttpServletRequest request )
176     {
177     	ReferenceList listTypes = getSecurityHeaderService( ).getTypeList( );
178         ReferenceList listPageCategories = getSecurityHeaderService( ).getPageCategoryList( );
179    
180         HashMap<String, Object> model = new HashMap<>( );
181         model.put( MARK_TYPES_LIST, listTypes );
182         model.put( MARK_PAGE_CATEGORY_LIST, listPageCategories );
183         if ( !listTypes.isEmpty( ) )
184         {
185             model.put( MARK_TYPE_SELECTED, listTypes.get( 0 ).getCode( ) );
186         }
187         
188         if ( !listPageCategories.isEmpty( ) )
189         {
190             model.put( MARK_PAGE_CATEGORY_SELECTED, listPageCategories.get( 0 ).getCode( ) );
191         }
192         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_CREATE_SECURITYHEADER ) );
193         
194         return model;
195     }
196     
197     /**
198      * Process the data capture form for create a security header
199      *
200      * @param request
201      *            The HTTP Request
202      * @return The Jsp URL of the process result
203      * @throws AccessDeniedException
204      *             If the security token is invalid
205      */
206     public String doCreateSecurityHeader( HttpServletRequest request ) throws AccessDeniedException
207     {
208         SecurityHeadertyheader/SecurityHeader.html#SecurityHeader">SecurityHeader securityHeader = new SecurityHeader( );        
209         String strErrors = processCreationFormData( request, securityHeader );
210         
211         if ( strErrors != null )
212         {
213             return AdminMessageService.getMessageUrl( request, strErrors, AdminMessage.TYPE_STOP );
214         }
215 
216         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_CREATE_SECURITYHEADER ) )
217         {
218             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
219         }
220         
221         getSecurityHeaderService( ).create( securityHeader );
222 
223         return JSP_MANAGE_SECURITY_HEADERS;
224     }
225     
226     /**
227      * Process Creation Form Data.
228      * 
229      * @param request
230      *            The HTTP request
231      * @param securityheader
232      *            The security header
233      * @return An Error message or null if no error
234      */
235     private String processCreationFormData( HttpServletRequest request, SecurityHeader securityHeader )
236     {
237         securityHeader.setName( request.getParameter( PARAMETER_NAME ) );
238         securityHeader.setValue( request.getParameter( PARAMETER_VALUE ) );
239         securityHeader.setDescription( request.getParameter( PARAMETER_DESCRIPTION ) );
240         securityHeader.setType( request.getParameter( PARAMETER_TYPE ) );
241         securityHeader.setPageCategory( getPageCategory( request.getParameter( PARAMETER_PAGE_CATEGORY ), securityHeader.getType( ) ) );
242         
243         String strErrors = processCommonControls( securityHeader );
244         if( strErrors != null )
245         {
246         	return strErrors;
247         }
248 
249         if( !isSecurityHeaderToCreateUnique( securityHeader ) )
250         {
251         	return MESSAGE_HEADER_ALREADY_EXIST;
252         }
253         
254         return null;
255     }
256     
257     
258     /**
259      * Executes common controls between creation and modification actions on request parameters
260      * 
261      * @param securityHeader
262      *           Security header to control
263      * @return null if controls are passed, an string containing an error message otherwise
264      */
265     private String processCommonControls( SecurityHeader securityHeader )
266     {
267         
268     	if( !validateBean( securityHeader, VALIDATION_ATTRIBUTES_PREFIX ) )
269     	{
270     		List<ErrorMessage> listErrors = ( List<ErrorMessage> ) getModel( ).get( MARK_ERRORS );
271     		return listErrors.get( 0 ).getMessage( );
272     	}
273 
274     	if( !isTypeBelongsToReferenceList ( securityHeader.getType( ) ) )
275     	{
276     		return MESSAGE_TYPE_UNKNOWN;
277     	}
278     	
279     	if( securityHeader.getPageCategory( ) != null && !isPageCategoryBelongsToReferenceList ( securityHeader.getPageCategory( ) ) )
280     	{
281     		return MESSAGE_PAGE_CATEGORY_UNKNOWN;
282     	}
283     	
284         if( SecurityHeaderType.PAGE.getCode( ).equals( securityHeader.getType( ) ) && StringUtils.isEmpty( securityHeader.getPageCategory( ) ) )
285         {
286         	return MESSAGE_PAGE_CATEGORY_REQUIRED_WHEN_PAGE_IS_TYPE;
287         }
288         
289         return null;
290     }
291     
292     /**
293      * Checks if specified type is found in the reference list of security headers types 
294      * 
295      * @param strType
296      *         THe security header type
297      * @return true if type belongs to the reference types list, false otherwise
298      */
299     private boolean isTypeBelongsToReferenceList( String strType )
300     {
301     	for (ReferenceItem referenceType : getSecurityHeaderService( ).getTypeList( ) )
302     	{
303     		if ( strType.equals( referenceType.getCode() ) )
304     		{
305     			return true;
306     		}
307     	}
308     	
309     	return false;
310     }
311     
312     /**
313      * Checks if specified page category is found in the reference list of security headers page categories 
314      * 
315      * @param strPageCategory
316      *         The security header page category
317      * @return true if page category belongs to the reference types list, false otherwise
318      */
319     private boolean isPageCategoryBelongsToReferenceList( String strPageCategory )
320     {
321     	for (ReferenceItem referencePageCategory : getSecurityHeaderService( ).getPageCategoryList( ) )
322     	{
323     		if ( strPageCategory.equals( referencePageCategory.getCode() ) )
324     		{
325     			return true;
326     		}
327     	}
328     	
329     	return false;
330     }
331     
332     /**
333      * Checks if the security header to create doesn't already exist to prevent duplicates.
334      * The criteria used to determine if a security header is unique are name, type and page category (in case of security header type is equals to page).
335      * 
336      * @param securityHeaderToCreate
337      *            The security header to create
338      * @return true if the security header doesn't exist, false otherwise
339      */
340     private boolean isSecurityHeaderToCreateUnique( SecurityHeader securityHeaderToCreate )
341     {	
342     	return getSecurityHeaderService( ).find( securityHeaderToCreate.getName( ), securityHeaderToCreate.getType( ) , securityHeaderToCreate.getPageCategory( ) ).isEmpty( );
343     }
344     
345     /**
346      * Returns the security header modification page.
347      * 
348      * @param request
349      *            the http request
350      * @return the html code for the securityheader modification page
351      */
352     public String getModifySecurityHeader( HttpServletRequest request )
353     {
354         setPageTitleProperty( PROPERTY_MODIFY_SECURITYHEADER_PAGETITLE );
355 
356         String strSecurityHeaderId = request.getParameter( PARAMETER_SECURITY_HEADER_ID );
357 
358         if ( !StringUtils.isNumeric( strSecurityHeaderId ) )
359         {
360             AppLogService.error( " {} is not a valid security header id.", ( ) -> SecurityUtil.logForgingProtect( strSecurityHeaderId ) );
361 
362             return getManageSecurityHeaders( request );
363         }
364         
365         SecurityHeader securityHeader = getSecurityHeaderForModification( strSecurityHeaderId );
366         if ( securityHeader == null )
367         {
368             AppLogService.error( "{} is not a valid security header id.", ( ) -> SecurityUtil.logForgingProtect( strSecurityHeaderId ) );
369 
370             return getManageSecurityHeaders( request );
371         }
372 
373         HashMap<String, Object> model = createModelForHeaderModification( request, securityHeader );
374         HtmlTemplate template = AppTemplateService.getTemplate( TEMPLATE_MODIFY_SECURITYHEADER, getLocale( ), model );
375 
376         return getAdminPage( template.getHtml( ) );
377     }
378 
379     /**
380      * This method returns the security header to modify. Value field is escaped because some headers values can have double quotes 
381      * (Clear-site-data header for instance) and in this case, the value is not displayed on the modification screen
382      * 
383      * @param strSecurityHeaderId
384      *          The security header id
385      * @return security header to modify
386      */
387     private SecurityHeader getSecurityHeaderForModification( String strSecurityHeaderId )
388     {
389     	SecurityHeader securityHeader = SecurityHeaderHome.findByPrimaryKey( Integer.parseInt( strSecurityHeaderId ) );
390     	if( securityHeader != null )
391     	{
392             securityHeader.setValue( StringEscapeUtils.escapeHtml4( securityHeader.getValue( ) ) );
393     	}
394         
395         return securityHeader;
396     }
397     
398     /**
399      * Returns the message page that informs that a security header is not editable.
400      *
401      * @param request
402      *            The Http Request
403      * @return the confirmation url
404      */
405     public String getMessageNotEditableSecurityHeader( HttpServletRequest request )
406     {  	 
407         return AdminMessageService.getMessageUrl( request, MESSAGE_ACTIVE_HEADER_NOT_EDITABLE, AdminMessage.TYPE_INFO );
408     }
409       
410     /**
411      * 
412      * Creates the model used for modifying a security header.
413      * 
414      * @param request
415      *            The HttpServletRequest
416      * @return model map
417      */
418 	private HashMap<String, Object> createModelForHeaderModification(HttpServletRequest request, SecurityHeader securityHeader) 
419 	{
420 		ReferenceList listTypes = getSecurityHeaderService().getTypeList( );
421         ReferenceList listPageCategories = getSecurityHeaderService().getPageCategoryList( );
422 
423         HashMap<String, Object> model = new HashMap<>( );
424         model.put( MARK_TYPES_LIST, listTypes );
425         model.put( MARK_PAGE_CATEGORY_LIST, listPageCategories );        
426         model.put( MARK_TYPE_SELECTED, securityHeader.getType() );
427         String selectedCategory = null;
428         if(securityHeader.getType().equals(SecurityHeaderType.PAGE.getCode()))
429         {
430         	selectedCategory = securityHeader.getPageCategory();
431         }
432         else
433         {
434         	selectedCategory = listPageCategories.get( 0 ).getCode( );
435         }
436         model.put( MARK_PAGE_CATEGORY_SELECTED, selectedCategory );
437         model.put( MARK_SECURITY_HEADER, securityHeader );
438         model.put( SecurityTokenService.MARK_TOKEN, SecurityTokenService.getInstance( ).getToken( request, TEMPLATE_MODIFY_SECURITYHEADER ) );
439 		return model;
440 	}
441     
442     /**
443      * Processes the data capture form for modifying a security header.
444      *
445      * @param request
446      *            The HTTP Request
447      * @return The Jsp URL of the process result
448      * @throws AccessDeniedException
449      *             if the security token is invalid
450      */
451     public String doModifySecurityHeader( HttpServletRequest request ) throws AccessDeniedException
452     {
453         int nId = Integer.parseInt( request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
454         SecurityHeader securityHeader = SecurityHeaderHome.findByPrimaryKey( nId );
455 
456         String strErrors = processModifyFormData( request, securityHeader );
457 
458         if ( strErrors != null )
459         {
460             return AdminMessageService.getMessageUrl( request, strErrors, AdminMessage.TYPE_STOP );
461         }
462         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MODIFY_SECURITYHEADER ) )
463         {
464             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
465         }
466 
467         getSecurityHeaderService( ).update( securityHeader );
468 
469         return getHomeUrl( request );
470     }
471     
472     /**
473      * Processes Modify Form Data.
474      * 
475      * @param request
476      *            The HTTP request
477      * @param securityheader
478      *            The security header
479      * @return An Error message or null if no error
480      */
481     private String processModifyFormData( HttpServletRequest request, SecurityHeader securityHeader )
482     {
483     	securityHeader.setName( request.getParameter( PARAMETER_NAME ) );
484     	securityHeader.setValue( request.getParameter( PARAMETER_VALUE ) );
485     	securityHeader.setDescription( request.getParameter( PARAMETER_DESCRIPTION ) );
486     	securityHeader.setType( request.getParameter( PARAMETER_TYPE ) );
487     	securityHeader.setPageCategory( getPageCategory( request.getParameter( PARAMETER_PAGE_CATEGORY ), securityHeader.getType( ) ) );
488         
489         String strErrors = processCommonControls( securityHeader );
490         if( strErrors != null )
491         {
492         	return strErrors;
493         }
494         
495         if( !isSecurityHeaderToModifyUnique( securityHeader, securityHeader.getName( ), securityHeader.getType( ), securityHeader.getPageCategory( )  ) )
496         {
497         	return MESSAGE_HEADER_ALREADY_EXIST;
498         }
499         
500         return null;
501     }
502     
503     /**
504      * Returns security header page category from request if security header type is page. 
505      * If type is REST api, page category is not relevant and should not be filled so the method returns null.
506      * 
507      * @param strType
508      * @param strPageCategoryFromRequest
509      * @return
510      */
511     private String getPageCategory( String strPageCategoryFromRequest, String strType )
512     { 	
513     	if( SecurityHeaderType.PAGE.getCode( ).equals( strType ) )
514     	{
515     		return strPageCategoryFromRequest ;
516     	}
517     	
518     	return null;
519     }
520     
521     /**
522      * Checks if the security header to modify will be always unique after modifications are applied to prevent duplicates.
523      * The criteria used to determine if a security header is unique are name, type and page category (in case of security header type is equals to page).
524      * 
525      * @param securityHeaderToModify
526      *            The security header to modify
527      * @param strName
528      *            The name to set  
529      * @param strType
530      *            The type to set
531      * @param strPageCategory
532      *            The page category to set
533      * @return true if the security header after modification will be still unique, false otherwise
534      */
535     private boolean isSecurityHeaderToModifyUnique( SecurityHeader securityHeaderToModify, String strName, String strType, String strPageCategory )
536     {	
537     	for( SecurityHeader securityHeader : getSecurityHeaderService( ).find( strName, strType, strPageCategory ) )
538     	{
539     		if( securityHeaderToModify.getId( ) != securityHeader.getId( ) )
540     		{
541     			return false;
542     		}   			
543     	}
544     	
545     	return true;
546     }
547     
548     /**
549      * Returns the page of confirmation for deleting a security header.
550      *
551      * @param request
552      *            The Http Request
553      * @return the confirmation url
554      */
555     public String getConfirmRemoveSecurityHeader( HttpServletRequest request )
556     {  	
557     	Map<String, String> parameters = new HashMap<>( );
558         parameters.put( PARAMETER_SECURITY_HEADER_ID, request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
559         parameters.put( SecurityTokenService.PARAMETER_TOKEN, SecurityTokenService.getInstance( ).getToken( request, JSP_REMOVE_SECURITY_HEADERS ) );
560         
561         return AdminMessageService.getMessageUrl( request, MESSAGE_CONFIRM_REMOVE, JSP_REMOVE_SECURITY_HEADERS, AdminMessage.TYPE_CONFIRMATION, parameters );
562     }
563     
564     /**
565      * Processes the data capture form for removing a security header.
566      *
567      * @param request
568      *            The HTTP Request
569      * @return The Jsp URL of the process result
570      * @throws AccessDeniedException
571      *             if the security token is invalid
572      */
573     public String doRemoveSecurityHeader( HttpServletRequest request ) throws AccessDeniedException
574     {
575     	if ( !SecurityTokenService.getInstance( ).validate( request, JSP_REMOVE_SECURITY_HEADERS ) )
576         {
577             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
578         }
579     	String strId = request.getParameter( PARAMETER_SECURITY_HEADER_ID );
580     	getSecurityHeaderService( ).remove( Integer.parseInt( strId ) );
581     	
582     	return JSP_MANAGE_SECURITY_HEADERS;
583     }
584     
585     /**
586      * Processes the security headers actions (enable and disable).
587      * 
588      * @param request
589      *            The HTTP request
590      * @return The forward URL
591      * @throws AccessDeniedException
592      *             if the security token is invalid
593      */
594     public String doSecurityHeaderAction( HttpServletRequest request ) throws AccessDeniedException
595     {
596         String strAction = request.getParameter( PARAMETER_ACTION );
597         int nId = Integer.parseInt( request.getParameter( PARAMETER_SECURITY_HEADER_ID ) );
598         
599         if ( !SecurityTokenService.getInstance( ).validate( request, TEMPLATE_MANAGE_SECURITY_HEADERS ) )
600         {
601             throw new AccessDeniedException( ERROR_INVALID_TOKEN );
602         }
603         switch( strAction )
604         {
605             case ACTION_ENABLE:
606             	getSecurityHeaderService( ).enable( nId );
607                 break;
608             case ACTION_DISABLE:
609             	getSecurityHeaderService( ).disable( nId );
610                 break;
611             default:
612                 AppLogService.error( "Unknown security header action : {}", strAction );
613         }
614 
615         return getHomeUrl( request );
616     }
617     
618     /**
619      * Returns the security header service.
620      * 
621      * @return the security header service
622      */
623     private SecurityHeaderService getSecurityHeaderService( )
624     {
625     	return SpringContextService.getBean( "securityHeaderService" );
626     }
627 }