/
ViewConfigSecurityEnforcer.java
121 lines (111 loc) · 4.73 KB
/
ViewConfigSecurityEnforcer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package org.jboss.seam.faces.view.config;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.logging.Level;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PhaseEvent;
import javax.inject.Inject;
import javax.security.auth.login.LoginException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletResponse;
import org.jboss.logging.Logger;
import org.jboss.seam.faces.event.PhaseIdType;
import org.jboss.seam.faces.event.qualifier.After;
import org.jboss.seam.faces.event.qualifier.Before;
import org.jboss.seam.faces.event.qualifier.InvokeApplication;
import org.jboss.seam.faces.event.qualifier.RenderResponse;
import org.jboss.seam.faces.event.qualifier.RestoreView;
import org.jboss.seam.security.annotations.SecurityBindingType;
import org.jboss.seam.solder.core.Requires;
/**
* Use the annotations stored in the ViewConfigStore to restrict view access
*
* @author <a href="mailto:bleathem@gmail.com">Brian Leathem</a>
*/
@Requires("org.jboss.seam.security.extension.SecurityExtension")
public class ViewConfigSecurityEnforcer
{
private transient final Logger log = Logger.getLogger(ViewConfigSecurityEnforcer.class);
@Inject
private ViewConfigStore viewConfigStore;
@Inject
private Event<SecurityCheckEvent> securityCheckEvent;
public void observeRenderResponse(@Observes @Before @RenderResponse PhaseEvent event)
{
log.info("Before Render Response event");
performObservation(event, PhaseIdType.RENDER_RESPONSE);
}
public void observeInvokeApplication(@Observes @Before @InvokeApplication PhaseEvent event)
{
log.info("Before Render Response event");
performObservation(event, PhaseIdType.INVOKE_APPLICATION);
}
public void observeRestoreView(@Observes @After @RestoreView PhaseEvent event)
{
log.info("After Restore View event");
performObservation(event, PhaseIdType.RESTORE_VIEW);
}
private void performObservation(PhaseEvent event, PhaseIdType phaseIdType)
{
UIViewRoot viewRoot = (UIViewRoot) event.getFacesContext().getViewRoot();
if (isRestrictPhase(phaseIdType, viewRoot.getViewId(), event.getFacesContext().isPostback()))
{
log.infof("Enforcing on phase %s", phaseIdType);
enforce(event.getFacesContext(), viewRoot);
}
}
public boolean isRestrictPhase(PhaseIdType currentPhase, String viewId, boolean isPostback)
{
RestrictAtPhase restrictAtPhase = viewConfigStore.getAnnotationData(viewId, RestrictAtPhase.class);
PhaseIdType restrictAtPhaseType = null;
if (restrictAtPhase != null)
{
restrictAtPhaseType = isPostback ? restrictAtPhase.postback() : restrictAtPhase.initial();
}
if (restrictAtPhaseType == null)
{
restrictAtPhaseType = isPostback ? RestrictAtPhaseDefault.RESTRICT_POSTBACK_DEFAULT : RestrictAtPhaseDefault.RESTRICT_INITIAL_DEFAULT;
}
return restrictAtPhaseType.equals(currentPhase);
}
private void enforce(FacesContext facesContext, UIViewRoot viewRoot)
{
List<? extends Annotation> annotations = viewConfigStore.getAllQualifierData(viewRoot.getViewId(), SecurityBindingType.class);
if (annotations == null || annotations.isEmpty())
{
log.info("Annotations is null/empty");
return;
}
SecurityCheckEvent securityEvent = new SecurityCheckEvent(annotations);
securityCheckEvent.fire(securityEvent);
if (! securityEvent.isAuthorized())
{
LoginView loginView = viewConfigStore.getAnnotationData(viewRoot.getViewId(), LoginView.class);
if (loginView == null || loginView.value() == null || loginView.value().isEmpty())
{
facesContext.getExternalContext().setResponseStatus(401);
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
try {
response.sendError(401);
} catch (IOException ex) {
throw new FacesException("Error writing to HttpServlerResponse", ex);
}
facesContext.responseComplete();
return;
}
String loginViewId = loginView.value();
NavigationHandler navHandler = facesContext.getApplication().getNavigationHandler();
navHandler.handleNavigation(facesContext, "", loginViewId);
facesContext.renderResponse();
return;
}
log.info("Access granted");
}
}