390163 Implement ServletRegistration.Dynamic.setServletSecurity
This commit is contained in:
parent
c7e36470c5
commit
ce3ba58887
|
@ -21,6 +21,7 @@ package org.eclipse.jetty.annotations;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletSecurityElement;
|
||||
import javax.servlet.annotation.HttpConstraint;
|
||||
import javax.servlet.annotation.HttpMethodConstraint;
|
||||
import javax.servlet.annotation.ServletSecurity;
|
||||
|
@ -30,12 +31,13 @@ import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
|
|||
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
|
||||
import org.eclipse.jetty.security.ConstraintAware;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.servlet.ServletMapping;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
import org.eclipse.jetty.webapp.Origin;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
/**
|
||||
|
@ -82,7 +84,7 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
|
|||
if (servletSecurity == null)
|
||||
return;
|
||||
|
||||
//If there are already constraints defined (ie from web.xml or programmatically(?)) that match any
|
||||
//If there are already constraints defined (ie from web.xml) that match any
|
||||
//of the url patterns defined for this servlet, then skip the security annotation.
|
||||
|
||||
List<ServletMapping> servletMappings = getServletMappings(clazz.getCanonicalName());
|
||||
|
@ -97,19 +99,15 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
|
|||
//Make a fresh list
|
||||
constraintMappings = new ArrayList<ConstraintMapping>();
|
||||
|
||||
//Get the values that form the constraints that will apply unless there are HttpMethodConstraints to augment them
|
||||
HttpConstraint defaults = servletSecurity.value();
|
||||
|
||||
//Make a Constraint for the <auth-constraint> and <user-data-constraint> specified by the HttpConstraint
|
||||
Constraint defaultConstraint = makeConstraint (clazz,
|
||||
defaults.rolesAllowed(),
|
||||
defaults.value(),
|
||||
defaults.transportGuarantee());
|
||||
|
||||
constraintMappings.addAll(makeMethodMappings(clazz,
|
||||
defaultConstraint,
|
||||
servletMappings,
|
||||
servletSecurity.httpMethodConstraints()));
|
||||
ServletSecurityElement securityElement = new ServletSecurityElement(servletSecurity);
|
||||
for (ServletMapping sm : servletMappings)
|
||||
{
|
||||
for (String url : sm.getPathSpecs())
|
||||
{
|
||||
_context.getMetaData().setOrigin("constraint.url."+url, Origin.Annotation);
|
||||
constraintMappings.addAll(ConstraintSecurityHandler.createConstraintsWithMappingsForPath(clazz.getName(), url, securityElement));
|
||||
}
|
||||
}
|
||||
|
||||
//set up the security constraints produced by the annotation
|
||||
ConstraintAware securityHandler = (ConstraintAware)_context.getSecurityHandler();
|
||||
|
@ -131,111 +129,10 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
|
|||
*/
|
||||
protected Constraint makeConstraint (Class servlet, String[] rolesAllowed, EmptyRoleSemantic permitOrDeny, TransportGuarantee transport)
|
||||
{
|
||||
Constraint constraint = new Constraint();
|
||||
if (rolesAllowed == null || rolesAllowed.length==0)
|
||||
{
|
||||
if (permitOrDeny.equals(EmptyRoleSemantic.DENY))
|
||||
{
|
||||
//Equivalent to <auth-constraint> with no roles
|
||||
constraint.setName(servlet.getName()+"-Deny");
|
||||
constraint.setAuthenticate(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Equivalent to no <auth-constraint>
|
||||
constraint.setAuthenticate(false);
|
||||
constraint.setName(servlet.getName()+"-Permit");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Equivalent to <auth-constraint> with list of <security-role-name>s
|
||||
constraint.setAuthenticate(true);
|
||||
constraint.setRoles(rolesAllowed);
|
||||
constraint.setName(servlet.getName()+"-RolesAllowed");
|
||||
}
|
||||
|
||||
//Equivalent to //<user-data-constraint><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>
|
||||
constraint.setDataConstraint((transport.equals(TransportGuarantee.CONFIDENTIAL)?Constraint.DC_CONFIDENTIAL:Constraint.DC_NONE));
|
||||
return constraint;
|
||||
return ConstraintSecurityHandler.createConstraint(servlet.getName(), rolesAllowed, permitOrDeny, transport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a ConstraintMapping which captures the <http-method> or <http-method-omission> elements for a particular url pattern,
|
||||
* and relates it to a Constraint object (<auth-constraint> and <user-data-constraint>).
|
||||
* @param constraint
|
||||
* @param url
|
||||
* @param method
|
||||
* @param omissions
|
||||
* @return
|
||||
*/
|
||||
protected ConstraintMapping makeConstraintMapping (Constraint constraint, String url, String method, String[] omissions)
|
||||
{
|
||||
ConstraintMapping mapping = new ConstraintMapping();
|
||||
mapping.setConstraint(constraint);
|
||||
mapping.setPathSpec(url);
|
||||
if (method != null)
|
||||
mapping.setMethod(method);
|
||||
if (omissions != null)
|
||||
mapping.setMethodOmissions(omissions);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the Jetty Constraints and ConstraintMapping objects that correspond to the HttpMethodConstraint
|
||||
* annotations for each url pattern for the servlet.
|
||||
* @param servlet
|
||||
* @param defaultConstraint
|
||||
* @param servletMappings
|
||||
* @param annotations
|
||||
* @return
|
||||
*/
|
||||
protected List<ConstraintMapping> makeMethodMappings (Class servlet, Constraint defaultConstraint, List<ServletMapping> servletMappings, HttpMethodConstraint[] annotations)
|
||||
{
|
||||
List<ConstraintMapping> mappings = new ArrayList<ConstraintMapping>();
|
||||
|
||||
//for each url-pattern existing for the servlet make a ConstraintMapping for the HttpConstraint, and ConstraintMappings for
|
||||
//each HttpMethodConstraint
|
||||
for (ServletMapping sm : servletMappings)
|
||||
{
|
||||
for (String url : sm.getPathSpecs())
|
||||
{
|
||||
//Make a ConstraintMapping that matches the defaultConstraint
|
||||
ConstraintMapping defaultMapping = makeConstraintMapping(defaultConstraint, url, null, null);
|
||||
|
||||
//If there are HttpMethodConstraint annotations, make a Constraint and a ConstraintMapping for it
|
||||
if (annotations != null && annotations.length>0)
|
||||
{
|
||||
List<String> omissions = new ArrayList<String>();
|
||||
|
||||
//for each HttpMethodConstraint annotation, make a new Constraint and ConstraintMappings for this url
|
||||
for (int i=0; i < annotations.length;i++)
|
||||
{
|
||||
//Make a Constraint that captures the <auth-constraint> and <user-data-constraint> elements
|
||||
Constraint methodConstraint = makeConstraint(servlet,
|
||||
annotations[i].rolesAllowed(),
|
||||
annotations[i].emptyRoleSemantic(),
|
||||
annotations[i].transportGuarantee());
|
||||
|
||||
//Make ConstraintMapping that captures the <http-method> elements
|
||||
ConstraintMapping methodConstraintMapping = makeConstraintMapping (methodConstraint,
|
||||
url,annotations[i].value(),
|
||||
null);
|
||||
mappings.add(methodConstraintMapping);
|
||||
omissions.add(annotations[i].value());
|
||||
}
|
||||
defaultMapping.setMethodOmissions(omissions.toArray(new String[0]));
|
||||
}
|
||||
|
||||
//add the constraint mapping containing the http-method-omissions, if there are any
|
||||
mappings.add(defaultMapping);
|
||||
}
|
||||
}
|
||||
return mappings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the ServletMappings for the servlet's class.
|
||||
|
@ -284,6 +181,7 @@ public class ServletSecurityAnnotationHandler extends AbstractIntrospectableAnno
|
|||
{
|
||||
for (int j=0; j < pathSpecs.length; j++)
|
||||
{
|
||||
//TODO decide if we need to check the origin
|
||||
if (pathSpecs[j].equals(constraintMappings.get(i).getPathSpec()))
|
||||
{
|
||||
exists = true;
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Arrays;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -51,7 +50,7 @@ import org.eclipse.jetty.util.security.Constraint;
|
|||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Handler to enforce SecurityConstraints. This implementation is servlet spec
|
||||
* 2.4 compliant and precomputes the constraint combinations for runtime
|
||||
* 3.0 compliant and precomputes the constraint combinations for runtime
|
||||
* efficiency.
|
||||
*
|
||||
*/
|
||||
|
@ -191,9 +190,11 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
/** Take out of the constraint mappings those that match the
|
||||
* given path.
|
||||
*
|
||||
* @param pathSpec
|
||||
* @param constraintMappings
|
||||
* @param constraintMappings a new list minus the matching constraints
|
||||
* @return
|
||||
*/
|
||||
public static List<ConstraintMapping> removeConstraintMappingsForPath(String pathSpec, List<ConstraintMapping> constraintMappings)
|
||||
|
@ -351,8 +352,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
*/
|
||||
public void setConstraintMappings(List<ConstraintMapping> constraintMappings, Set<String> roles)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Started");
|
||||
_constraintMappings.clear();
|
||||
_constraintMappings.addAll(constraintMappings);
|
||||
|
||||
|
@ -371,6 +370,14 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
}
|
||||
}
|
||||
setRoles(roles);
|
||||
|
||||
if (isStarted())
|
||||
{
|
||||
for (ConstraintMapping mapping : _constraintMappings)
|
||||
{
|
||||
processConstraintMapping(mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -383,9 +390,6 @@ public class ConstraintSecurityHandler extends SecurityHandler implements Constr
|
|||
*/
|
||||
public void setRoles(Set<String> roles)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Started");
|
||||
|
||||
_roles.clear();
|
||||
_roles.addAll(roles);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ import javax.servlet.descriptor.JspPropertyGroupDescriptor;
|
|||
import javax.servlet.descriptor.TaglibDescriptor;
|
||||
|
||||
import org.eclipse.jetty.security.ConstraintAware;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.security.SecurityHandler;
|
||||
import org.eclipse.jetty.server.Dispatcher;
|
||||
|
@ -59,6 +60,7 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
|
|||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.util.LazyList;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -377,10 +379,21 @@ public class ServletContextHandler extends ContextHandler
|
|||
* @param registration ServletRegistration.Dynamic instance that setServletSecurity was called on
|
||||
* @param servletSecurityElement new security info
|
||||
* @return the set of exact URL mappings currently associated with the registration that are also present in the web.xml
|
||||
* security constratins and thus will be unaffected by this call.
|
||||
* security constraints and thus will be unaffected by this call.
|
||||
*/
|
||||
public Set<String> setServletSecurity(ServletRegistration.Dynamic registration, ServletSecurityElement servletSecurityElement)
|
||||
{
|
||||
//Default implementation is to just accept them all. If using a webapp, then this behaviour is overridden in WebAppContext.setServletSecurity
|
||||
Collection<String> pathSpecs = registration.getMappings();
|
||||
if (pathSpecs != null)
|
||||
{
|
||||
for (String pathSpec:pathSpecs)
|
||||
{
|
||||
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
|
||||
for (ConstraintMapping m:mappings)
|
||||
((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
|
||||
}
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
|
|
|
@ -538,6 +538,15 @@ public class MetaData
|
|||
OriginInfo x = new OriginInfo (name, Origin.Annotation);
|
||||
_origins.put(name, x);
|
||||
}
|
||||
|
||||
public void setOrigin(String name, Origin origin)
|
||||
{
|
||||
if (name == null)
|
||||
return;
|
||||
|
||||
OriginInfo x = new OriginInfo (name, origin);
|
||||
_origins.put(name, x);
|
||||
}
|
||||
|
||||
public boolean isMetaDataComplete()
|
||||
{
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
|
||||
package org.eclipse.jetty.webapp;
|
||||
|
||||
public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation}
|
||||
public enum Origin {NotSet, WebXml, WebDefaults, WebOverride, WebFragment, Annotation, API}
|
|
@ -25,18 +25,29 @@ import java.net.URL;
|
|||
import java.security.PermissionCollection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EventListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.HttpMethodConstraintElement;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletRegistration.Dynamic;
|
||||
import javax.servlet.ServletSecurityElement;
|
||||
import javax.servlet.annotation.ServletSecurity.EmptyRoleSemantic;
|
||||
import javax.servlet.annotation.ServletSecurity.TransportGuarantee;
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionAttributeListener;
|
||||
import javax.servlet.http.HttpSessionBindingListener;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import org.eclipse.jetty.security.ConstraintAware;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
import org.eclipse.jetty.security.SecurityHandler;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HandlerContainer;
|
||||
|
@ -56,6 +67,7 @@ import org.eclipse.jetty.util.log.Log;
|
|||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.security.Constraint;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Web Application Context Handler.
|
||||
|
@ -1237,6 +1249,79 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
|
||||
super.startContext();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public Set<String> setServletSecurity(Dynamic registration, ServletSecurityElement servletSecurityElement)
|
||||
{
|
||||
|
||||
Set<String> unchangedURLMappings = new HashSet<String>();
|
||||
//From javadoc for ServletSecurityElement:
|
||||
/*
|
||||
If a URL pattern of this ServletRegistration is an exact target of a security-constraint that
|
||||
was established via the portable deployment descriptor, then this method does not change the
|
||||
security-constraint for that pattern, and the pattern will be included in the return value.
|
||||
|
||||
If a URL pattern of this ServletRegistration is an exact target of a security constraint
|
||||
that was established via the ServletSecurity annotation or a previous call to this method,
|
||||
then this method replaces the security constraint for that pattern.
|
||||
|
||||
If a URL pattern of this ServletRegistration is neither the exact target of a security constraint
|
||||
that was established via the ServletSecurity annotation or a previous call to this method,
|
||||
nor the exact target of a security-constraint in the portable deployment descriptor, then
|
||||
this method establishes the security constraint for that pattern from the argument ServletSecurityElement.
|
||||
*/
|
||||
|
||||
Collection<String> pathMappings = registration.getMappings();
|
||||
if (pathMappings != null)
|
||||
{
|
||||
Constraint constraint = ConstraintSecurityHandler.createConstraint(registration.getName(), servletSecurityElement);
|
||||
|
||||
for (String pathSpec:pathMappings)
|
||||
{
|
||||
Origin origin = getMetaData().getOrigin("constraint.url."+pathSpec);
|
||||
|
||||
switch (origin)
|
||||
{
|
||||
case NotSet:
|
||||
{
|
||||
//No mapping for this url already established
|
||||
List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
|
||||
for (ConstraintMapping m:mappings)
|
||||
((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
|
||||
getMetaData().setOrigin("constraint.url."+pathSpec, Origin.API);
|
||||
break;
|
||||
}
|
||||
case WebXml:
|
||||
case WebDefaults:
|
||||
case WebOverride:
|
||||
case WebFragment:
|
||||
{
|
||||
//a mapping for this url was created in a descriptor, which overrides everything
|
||||
unchangedURLMappings.add(pathSpec);
|
||||
break;
|
||||
}
|
||||
case Annotation:
|
||||
case API:
|
||||
{
|
||||
//mapping established via an annotation or by previous call to this method,
|
||||
//replace the security constraint for this pattern
|
||||
List<ConstraintMapping> constraintMappings = ConstraintSecurityHandler.removeConstraintMappingsForPath(pathSpec, ((ConstraintAware)getSecurityHandler()).getConstraintMappings());
|
||||
|
||||
List<ConstraintMapping> freshMappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
|
||||
constraintMappings.addAll(freshMappings);
|
||||
|
||||
((ConstraintSecurityHandler)getSecurityHandler()).setConstraintMappings(constraintMappings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return unchangedURLMappings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public class Context extends ServletContextHandler.Context
|
||||
|
@ -1287,6 +1372,8 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
|
|
@ -15,15 +15,6 @@
|
|||
<param-value>a context value</param-value>
|
||||
</context-param>
|
||||
|
||||
<!-- Add or override filter init parameter -->
|
||||
<filter>
|
||||
<filter-name>TestFilter</filter-name>
|
||||
<filter-class>com.acme.TestFilter</filter-class>
|
||||
<init-param>
|
||||
<param-name>remote</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
|
||||
<!-- Add or override servlet init parameter -->
|
||||
<servlet>
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package com.acme;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Rego Servlet - tests being accessed from servlet 3.0 programmatic
|
||||
* configuration.
|
||||
*
|
||||
*/
|
||||
public class RegTest extends HttpServlet
|
||||
{
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException
|
||||
{
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
doGet(request, response);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
PrintWriter pout=null;
|
||||
|
||||
try
|
||||
{
|
||||
pout =response.getWriter();
|
||||
}
|
||||
catch(IllegalStateException e)
|
||||
{
|
||||
pout=new PrintWriter(new OutputStreamWriter(response.getOutputStream(),"UTF-8"));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
pout.write("<html>\n<body>\n");
|
||||
pout.write("<h1>Rego Servlet</h1>\n");
|
||||
pout.write("<table width=\"95%\">");
|
||||
pout.write("<tr>\n");
|
||||
pout.write("<th align=\"right\">getMethod: </th>");
|
||||
pout.write("<td>" + notag(request.getMethod())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getContentLength: </th>");
|
||||
pout.write("<td>"+Integer.toString(request.getContentLength())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getContentType: </th>");
|
||||
pout.write("<td>"+notag(request.getContentType())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRequestURI: </th>");
|
||||
pout.write("<td>"+notag(request.getRequestURI())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRequestURL: </th>");
|
||||
pout.write("<td>"+notag(request.getRequestURL().toString())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getContextPath: </th>");
|
||||
pout.write("<td>"+request.getContextPath()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getServletPath: </th>");
|
||||
pout.write("<td>"+notag(request.getServletPath())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getPathInfo: </th>");
|
||||
pout.write("<td>"+notag(request.getPathInfo())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getPathTranslated: </th>");
|
||||
pout.write("<td>"+notag(request.getPathTranslated())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getQueryString: </th>");
|
||||
pout.write("<td>"+notag(request.getQueryString())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
|
||||
pout.write("<th align=\"right\">getProtocol: </th>");
|
||||
pout.write("<td>"+request.getProtocol()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getScheme: </th>");
|
||||
pout.write("<td>"+request.getScheme()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getServerName: </th>");
|
||||
pout.write("<td>"+notag(request.getServerName())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getServerPort: </th>");
|
||||
pout.write("<td>"+Integer.toString(request.getServerPort())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getLocalName: </th>");
|
||||
pout.write("<td>"+request.getLocalName()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getLocalAddr: </th>");
|
||||
pout.write("<td>"+request.getLocalAddr()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getLocalPort: </th>");
|
||||
pout.write("<td>"+Integer.toString(request.getLocalPort())+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRemoteUser: </th>");
|
||||
pout.write("<td>"+request.getRemoteUser()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getUserPrincipal: </th>");
|
||||
pout.write("<td>"+request.getUserPrincipal()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRemoteAddr: </th>");
|
||||
pout.write("<td>"+request.getRemoteAddr()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRemoteHost: </th>");
|
||||
pout.write("<td>"+request.getRemoteHost()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRemotePort: </th>");
|
||||
pout.write("<td>"+request.getRemotePort()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">getRequestedSessionId: </th>");
|
||||
pout.write("<td>"+request.getRequestedSessionId()+"</td>");
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">isSecure(): </th>");
|
||||
pout.write("<td>"+request.isSecure()+"</td>");
|
||||
|
||||
pout.write("</tr><tr>\n");
|
||||
pout.write("<th align=\"right\">isUserInRole(admin): </th>");
|
||||
pout.write("<td>"+request.isUserInRole("admin")+"</td>");
|
||||
|
||||
pout.write("</tr></table>");
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
getServletContext().log("dump "+e);
|
||||
}
|
||||
|
||||
|
||||
pout.write("</body>\n</html>\n");
|
||||
|
||||
pout.close();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String getServletInfo()
|
||||
{
|
||||
return "Rego Servlet";
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public synchronized void destroy()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private String notag(String s)
|
||||
{
|
||||
if (s==null)
|
||||
return "null";
|
||||
s=StringUtil.replace(s,"&","&");
|
||||
s=StringUtil.replace(s,"<","<");
|
||||
s=StringUtil.replace(s,">",">");
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package com.acme;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContextAttributeEvent;
|
||||
import javax.servlet.ServletContextAttributeListener;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
@ -26,6 +27,12 @@ import javax.servlet.ServletRequestAttributeEvent;
|
|||
import javax.servlet.ServletRequestAttributeListener;
|
||||
import javax.servlet.ServletRequestEvent;
|
||||
import javax.servlet.ServletRequestListener;
|
||||
import javax.servlet.ServletRegistration;
|
||||
import javax.servlet.FilterRegistration;
|
||||
import javax.servlet.ServletSecurityElement;
|
||||
import javax.servlet.HttpConstraintElement;
|
||||
import javax.servlet.HttpMethodConstraintElement;
|
||||
import javax.servlet.annotation.ServletSecurity;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSessionActivationListener;
|
||||
import javax.servlet.http.HttpSessionAttributeListener;
|
||||
|
@ -33,6 +40,9 @@ import javax.servlet.http.HttpSessionBindingEvent;
|
|||
import javax.servlet.http.HttpSessionEvent;
|
||||
import javax.servlet.http.HttpSessionListener;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TestListener implements HttpSessionListener, HttpSessionAttributeListener, HttpSessionActivationListener, ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener
|
||||
{
|
||||
public void attributeAdded(HttpSessionBindingEvent se)
|
||||
|
@ -62,16 +72,30 @@ public class TestListener implements HttpSessionListener, HttpSessionAttributeL
|
|||
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
/* TODO for servlet 3.0
|
||||
* FilterRegistration registration=context.addFilter("TestFilter",TestFilter.class.getName());
|
||||
|
||||
|
||||
//configure programmatic security
|
||||
ServletRegistration.Dynamic rego = sce.getServletContext().addServlet("RegoTest", RegTest.class.getName());
|
||||
rego.addMapping("/rego/*");
|
||||
HttpConstraintElement constraintElement = new HttpConstraintElement(ServletSecurity.EmptyRoleSemantic.PERMIT,
|
||||
ServletSecurity.TransportGuarantee.NONE, new String[]{"admin"});
|
||||
ServletSecurityElement securityElement = new ServletSecurityElement(constraintElement, null);
|
||||
Set<String> unchanged = rego.setServletSecurity(securityElement);
|
||||
System.err.println("Security constraints registered: "+unchanged.isEmpty());
|
||||
|
||||
//Test that a security constraint from web.xml can't be overridden programmatically
|
||||
ServletRegistration.Dynamic rego2 = sce.getServletContext().addServlet("RegoTest2", RegTest.class.getName());
|
||||
rego2.addMapping("/rego2/*");
|
||||
securityElement = new ServletSecurityElement(constraintElement, null);
|
||||
unchanged = rego2.setServletSecurity(securityElement);
|
||||
System.err.println("Overridding web.xml constraints not possible:" +!unchanged.isEmpty());
|
||||
|
||||
/* For servlet 3.0 */
|
||||
FilterRegistration.Dynamic registration = sce.getServletContext().addFilter("TestFilter",TestFilter.class.getName());
|
||||
registration.setInitParameter("remote", "false");
|
||||
registration.setAsyncSupported(true);
|
||||
registration.addMappingForUrlPatterns(
|
||||
EnumSet.of(DispatcherType.ERROR,DispatcherType.ASYNC,DispatcherType.FORWARD,DispatcherType.INCLUDE,DispatcherType.REQUEST),
|
||||
true,
|
||||
new String[]{"/dump/*","/dispatch/*","*.dump"});
|
||||
*/
|
||||
new String[]{"/*"});
|
||||
}
|
||||
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
|
|
|
@ -18,20 +18,6 @@
|
|||
<listener-class>com.acme.TestListener</listener-class>
|
||||
</listener>
|
||||
|
||||
<filter>
|
||||
<filter-name>TestFilter</filter-name>
|
||||
<filter-class>com.acme.TestFilter</filter-class>
|
||||
<async-support>true</async-support>
|
||||
<init-param>
|
||||
<param-name>remote</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
</filter>
|
||||
<filter-mapping>
|
||||
<filter-name>TestFilter</filter-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</filter-mapping>
|
||||
|
||||
|
||||
<filter>
|
||||
<filter-name>QoSFilter</filter-name>
|
||||
|
@ -120,7 +106,6 @@
|
|||
</filter-mapping>
|
||||
-->
|
||||
|
||||
|
||||
<servlet>
|
||||
<servlet-name>Hello</servlet-name>
|
||||
<servlet-class>com.acme.HelloWorld</servlet-class>
|
||||
|
@ -275,6 +260,18 @@
|
|||
<location>/error404.html</location>
|
||||
</error-page>
|
||||
|
||||
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Rego2</web-resource-name>
|
||||
<url-pattern>/rego2/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>server-administrator</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Auth2</web-resource-name>
|
||||
|
|
|
@ -18,6 +18,8 @@ This page contains several links to test the authentication constraints:
|
|||
<li><a href="dump/auth/info">dump/auth/*</a> - Authenticated any user</li>
|
||||
<li><a href="dump/auth/admin/info">dump/auth/admin/*</a> - Authenticated admin role (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li>
|
||||
<li><a href="dump/auth/ssl/info">dump/auth/ssl/*</a> - Confidential</li>
|
||||
<li><a href="rego/info">rego/info/*</a> - Authenticated admin role from programmatic security (<a href="session/?Action=Invalidate">click</a> to invalidate session)</li>
|
||||
<li><a href="rego2/info">rego2/info/*</a> - Authenticated servlet-administrator role from programmatic security (login as admin/admin, <a href="session/?Action=Invalidate">click</a> to invalidate session)</li>
|
||||
</ul>
|
||||
<p/>
|
||||
<p>
|
||||
|
|
Loading…
Reference in New Issue