@Test public void testExtensionMatchServletWithGlobalFilter() throws IOException, ServletException { DeploymentInfo builder = new DeploymentInfo(); final PathHandler root = new PathHandler(); final ServletContainer container = ServletContainer.Factory.newInstance(); builder.addServlet(new ServletInfo("*.jsp", PathMappingServlet.class).addMapping("*.jsp")); builder.addFilter(new FilterInfo("/*", PathFilter.class)); builder.addFilterUrlMapping("/*", "/*", DispatcherType.REQUEST); builder .setClassIntrospecter(TestClassIntrospector.INSTANCE) .setClassLoader(FilterPathMappingTestCase.class.getClassLoader()) .setContextPath("/servletContext") .setDeploymentName("servletContext.war"); final DeploymentManager manager = container.addDeployment(builder); manager.deploy(); root.addPrefixPath(builder.getContextPath(), manager.start()); DefaultServer.setRootHandler(root); TestHttpClient client = new TestHttpClient(); try { runTest(client, "aa.jsp", "*.jsp - /aa.jsp - null", "/*"); } finally { client.getConnectionManager().shutdown(); } }
public void handleDeploymentSessionConfig( DeploymentInfo deploymentInfo, ServletContextImpl servletContext) { SessionCookieConfigImpl sessionCookieConfig = servletContext.getSessionCookieConfig(); ServletSessionConfig sc = deploymentInfo.getServletSessionConfig(); if (sc != null) { sessionCookieConfig.setName(sc.getName()); sessionCookieConfig.setComment(sc.getComment()); sessionCookieConfig.setDomain(sc.getDomain()); sessionCookieConfig.setHttpOnly(sc.isHttpOnly()); sessionCookieConfig.setMaxAge(sc.getMaxAge()); if (sc.getPath() != null) { sessionCookieConfig.setPath(sc.getPath()); } else { sessionCookieConfig.setPath(deploymentInfo.getContextPath()); } sessionCookieConfig.setSecure(sc.isSecure()); if (sc.getSessionTrackingModes() != null) { servletContext.setDefaultSessionTrackingModes(new HashSet<>(sc.getSessionTrackingModes())); } } }
@BeforeClass public static void setup() throws Exception { js = UndertowJS.builder() .addResources( new ClassPathResourceManager( JavascriptSecurityTestCase.class.getClassLoader(), JavascriptSecurityTestCase.class.getPackage()), "security.js") .build(); js.start(); final ServletContainer container = ServletContainer.Factory.newInstance(); ServletIdentityManager identityManager = new ServletIdentityManager(); identityManager.addUser("user1", "password1", "admin"); identityManager.addUser("user2", "password2", "user"); DeploymentInfo builder = new DeploymentInfo() .setClassLoader(JavascriptSecurityTestCase.class.getClassLoader()) .setContextPath("/servletContext") .setDeploymentName("servletContext.war") .setIdentityManager(identityManager) .setLoginConfig(new LoginConfig("BASIC", "Test Realm")) .addInnerHandlerChainWrapper( new HandlerWrapper() { @Override public HttpHandler wrap(HttpHandler handler) { return js.getHandler(handler); } }); DeploymentManager manager = container.addDeployment(builder); manager.deploy(); PathHandler root = new PathHandler(); root.addPrefixPath(builder.getContextPath(), manager.start()); DefaultServer.setRootHandler(root); }
private void deployServlet(final ServerWebSocketContainer deployment) throws ServletException { final DeploymentInfo builder; builder = new DeploymentInfo() .setClassLoader(getClass().getClassLoader()) .setContextPath("/") .setClassIntrospecter(TestClassIntrospector.INSTANCE) .setDeploymentName("websocket.war") .addFilter(new FilterInfo("filter", JsrWebSocketFilter.class)) .addFilterUrlMapping("filter", "/*", DispatcherType.REQUEST) .addServletContextAttribute( javax.websocket.server.ServerContainer.class.getName(), deployment); final PathHandler root = new PathHandler(); final ServletContainer container = ServletContainer.Factory.newInstance(); DeploymentManager manager = container.addDeployment(builder); manager.deploy(); root.addPath(builder.getContextPath(), manager.start()); DefaultServer.setRootHandler(root); }
@BeforeClass public static void setup() throws ServletException { final PathHandler root = new PathHandler(); final ServletContainer container = ServletContainer.Factory.newInstance(); ServletInfo s = new ServletInfo("servlet", HelloServlet.class).addMapping("/aa"); DeploymentInfo builder = new DeploymentInfo() .setClassLoader(MockRequestTestCase.class.getClassLoader()) .setContextPath("/servletContext") .setClassIntrospecter(TestClassIntrospector.INSTANCE) .setDeploymentName("servletContext.war") .addServlet(s); DeploymentManager manager = container.addDeployment(builder); manager.deploy(); deployment = manager.getDeployment(); root.addPrefixPath(builder.getContextPath(), manager.start()); DefaultServer.setRootHandler(root); }
@Override public void handleDeployment(DeploymentInfo deploymentInfo, ServletContext servletContext) { if (!isAuthenticationMechanismPresent(deploymentInfo, "KEYCLOAK")) { log.info("auth-method is not keycloak!"); return; } log.info("KeycloakServletException initialization"); InputStream is = servletContext.getResourceAsStream("/WEB-INF/keycloak.json"); if (is == null) throw new RuntimeException("Unable to find /WEB-INF/keycloak.json configuration file"); RealmConfigurationLoader loader = new RealmConfigurationLoader(is); loader.init(true); AdapterConfig keycloakConfig = loader.getAdapterConfig(); RealmConfiguration realmConfiguration = loader.getRealmConfiguration(); PreflightCorsHandler.Wrapper preflight = new PreflightCorsHandler.Wrapper(keycloakConfig); UserSessionManagement userSessionManagement = new UserSessionManagement(realmConfiguration); ServletKeycloakAuthenticationMechanism auth = null; if (keycloakConfig.isBearerOnly()) { auth = new ServletKeycloakAuthenticationMechanism( keycloakConfig, loader.getResourceMetadata(), deploymentInfo.getConfidentialPortManager()); } else { auth = new ServletKeycloakAuthenticationMechanism( userSessionManagement, keycloakConfig, realmConfiguration, deploymentInfo.getConfidentialPortManager()); } ServletAuthenticatedActionsHandler.Wrapper actions = new ServletAuthenticatedActionsHandler.Wrapper(keycloakConfig); // setup handlers deploymentInfo.addInitialHandlerChainWrapper(preflight); // cors preflight deploymentInfo.addOuterHandlerChainWrapper( new ServletAdminActionsHandler.Wrapper(realmConfiguration, userSessionManagement)); final ServletKeycloakAuthenticationMechanism theAuth = auth; deploymentInfo.addAuthenticationMechanism( "KEYCLOAK", new AuthenticationMechanismFactory() { @Override public AuthenticationMechanism create( String s, FormParserFactory formParserFactory, Map<String, String> stringStringMap) { return theAuth; } }); // authentication deploymentInfo.addInnerHandlerChainWrapper( ServletPropagateSessionHandler.WRAPPER); // propagates SkeletonKeySession deploymentInfo.addInnerHandlerChainWrapper(actions); // handles authenticated actions and cors. deploymentInfo.setIdentityManager( new IdentityManager() { @Override public Account verify(Account account) { log.info("Verifying account in IdentityManager"); return account; } @Override public Account verify(String id, Credential credential) { log.warn("Shouldn't call verify!!!"); throw new IllegalStateException("Not allowed"); } @Override public Account verify(Credential credential) { log.warn("Shouldn't call verify!!!"); throw new IllegalStateException("Not allowed"); } }); log.info("Setting jsession cookie path to: " + deploymentInfo.getContextPath()); ServletSessionConfig cookieConfig = new ServletSessionConfig(); cookieConfig.setPath(deploymentInfo.getContextPath()); deploymentInfo.setServletSessionConfig(cookieConfig); }
@Test public void testBasicFilterMappings() throws IOException, ServletException { DeploymentInfo builder = new DeploymentInfo(); final PathHandler root = new PathHandler(); final ServletContainer container = ServletContainer.Factory.newInstance(); builder.addServlet(new ServletInfo("/a/*", PathMappingServlet.class).addMapping("/a/*")); builder.addServlet(new ServletInfo("/aa", PathMappingServlet.class).addMapping("/aa")); builder.addServlet(new ServletInfo("/", PathMappingServlet.class).addMapping("/")); builder.addServlet(new ServletInfo("contextRoot", PathMappingServlet.class).addMapping("")); builder.addServlet( new ServletInfo("/myservlet/*", PathMappingServlet.class).addMapping("/myservlet/*")); builder.addServlet(new ServletInfo("*.jsp", PathMappingServlet.class).addMapping("*.jsp")); builder.addServlet( new ServletInfo("/hello/*", PathMappingServlet.class).addMapping("/hello/*")); builder.addServlet(new ServletInfo("/test/*", PathMappingServlet.class).addMapping("/test/*")); builder.addFilter(new FilterInfo("/*", PathFilter.class)); builder.addFilterUrlMapping("/*", "/*", DispatcherType.REQUEST); // non standard, but we still support it builder.addFilter(new FilterInfo("*", PathFilter.class)); builder.addFilterUrlMapping("*", "*", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/a/*", PathFilter.class)); builder.addFilterUrlMapping("/a/*", "/a/*", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/aa", PathFilter.class)); builder.addFilterUrlMapping("/aa", "/aa", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("*.bop", PathFilter.class)); builder.addFilterUrlMapping("*.bop", "*.bop", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/myservlet/myfilter/*", PathFilter.class)); builder.addFilterUrlMapping( "/myservlet/myfilter/*", "/myservlet/myfilter/*", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/myfilter/*", PathFilter.class)); builder.addFilterUrlMapping("/myfilter/*", "/myfilter/*", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("contextRoot", PathFilter.class)); builder.addFilterServletNameMapping("contextRoot", "contextRoot", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("defaultName", PathFilter.class)); builder.addFilterServletNameMapping("defaultName", "/", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/helloworld/index.html", PathFilter.class)); builder.addFilterUrlMapping( "/helloworld/index.html", "/helloworld/index.html", DispatcherType.REQUEST); builder.addFilter(new FilterInfo("/test", PathFilter.class)); builder.addFilterUrlMapping("/test", "/test", DispatcherType.REQUEST); builder .setClassIntrospecter(TestClassIntrospector.INSTANCE) .setClassLoader(FilterPathMappingTestCase.class.getClassLoader()) .setContextPath("/servletContext") .setDeploymentName("servletContext.war"); final DeploymentManager manager = container.addDeployment(builder); manager.deploy(); root.addPrefixPath(builder.getContextPath(), manager.start()); DefaultServer.setRootHandler(root); TestHttpClient client = new TestHttpClient(); try { runTest(client, "test", "/test/* - /test - null", "/*", "*", "/test"); runTest(client, "aa", "/aa - /aa - null", "/*", "*", "/aa"); runTest(client, "a/c", "/a/* - /a - /c", "/*", "*", "/a/*"); runTest(client, "a", "/a/* - /a - null", "/*", "*", "/a/*"); runTest(client, "aa/b", "/ - /aa/b - null", "/*", "*", "defaultName"); runTest(client, "a/b/c/d", "/a/* - /a - /b/c/d", "/*", "*", "/a/*"); runTest(client, "defaultStuff", "/ - /defaultStuff - null", "/*", "*", "defaultName"); runTest(client, "", "contextRoot - / - null", "/*", "*", "contextRoot"); runTest(client, "yyyy.bop", "/ - /yyyy.bop - null", "/*", "*", "*.bop", "defaultName"); runTest(client, "a/yyyy.bop", "/a/* - /a - /yyyy.bop", "/*", "*", "*.bop", "/a/*"); runTest( client, "myservlet/myfilter/file.dat", "/myservlet/* - /myservlet - /myfilter/file.dat", "/*", "*", "/myservlet/myfilter/*"); runTest( client, "myservlet/myfilter/file.jsp", "/myservlet/* - /myservlet - /myfilter/file.jsp", "/*", "*", "/myservlet/myfilter/*"); runTest( client, "otherservlet/myfilter/file.jsp", "*.jsp - /otherservlet/myfilter/file.jsp - null", "/*", "*"); runTest( client, "myfilter/file.jsp", "*.jsp - /myfilter/file.jsp - null", "/*", "*", "/myfilter/*"); runTest( client, "helloworld/index.html", "/ - /helloworld/index.html - null", "/*", "*", "/helloworld/index.html", "defaultName"); } finally { client.getConnectionManager().shutdown(); } }
private void processDeployment( final WarMetaData warMetaData, final DeploymentUnit deploymentUnit, final ServiceTarget serviceTarget, String hostName) throws DeploymentUnitProcessingException { final VirtualFile deploymentRoot = deploymentUnit.getAttachment(Attachments.DEPLOYMENT_ROOT).getRoot(); final Module module = deploymentUnit.getAttachment(Attachments.MODULE); if (module == null) { throw new DeploymentUnitProcessingException(MESSAGES.failedToResolveModule(deploymentUnit)); } final DeploymentClassIndex deploymentClassIndex = deploymentUnit.getAttachment(Attachments.CLASS_INDEX); final JBossWebMetaData metaData = warMetaData.getMergedJBossWebMetaData(); final List<SetupAction> setupActions = deploymentUnit.getAttachmentList(org.jboss.as.ee.component.Attachments.WEB_SETUP_ACTIONS); ScisMetaData scisMetaData = deploymentUnit.getAttachment(ScisMetaData.ATTACHMENT_KEY); final Set<ServiceName> dependentComponents = new HashSet<>(); // see AS7-2077 // basically we want to ignore components that have failed for whatever reason // if they are important they will be picked up when the web deployment actually starts final List<ServiceName> components = deploymentUnit.getAttachmentList(WebComponentDescription.WEB_COMPONENTS); final Set<ServiceName> failed = deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.FAILED_COMPONENTS); for (final ServiceName component : components) { boolean skip = false; if (!failed.contains(component)) { dependentComponents.add(component); } } ComponentRegistry componentRegistry = deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.COMPONENT_REGISTRY); if (componentRegistry == null) { // we do this to avoid lots of other null checks // this will only happen if the EE subsystem is not installed componentRegistry = new ComponentRegistry(null); } final WebInjectionContainer injectionContainer = new WebInjectionContainer(module.getClassLoader(), componentRegistry); DeploymentInfo deploymentInfo = createServletConfig( metaData, deploymentUnit, module, deploymentClassIndex, injectionContainer, componentRegistry, scisMetaData, deploymentRoot); final String pathName = pathNameOfDeployment(deploymentUnit, metaData); deploymentInfo.setContextPath(pathName); String metaDataSecurityDomain = metaData.getSecurityDomain(); if (metaDataSecurityDomain == null) { metaDataSecurityDomain = getJBossAppSecurityDomain(deploymentUnit); } if (metaDataSecurityDomain != null) { metaDataSecurityDomain = metaDataSecurityDomain.trim(); } String securityDomain = metaDataSecurityDomain == null ? SecurityConstants.DEFAULT_APPLICATION_POLICY : SecurityUtil.unprefixSecurityDomain(metaDataSecurityDomain); final ServiceName deploymentServiceName = UndertowService.deploymentServiceName(hostName, deploymentInfo.getContextPath()); final ServiceName hostServiceName = UndertowService.virtualHostName(defaultServer, hostName); final UndertowDeploymentService service = new UndertowDeploymentService( deploymentInfo, injectionContainer, module, warMetaData.getMergedJBossWebMetaData()); final ServiceBuilder<UndertowDeploymentService> builder = serviceTarget .addService(deploymentServiceName, service) .addDependencies(dependentComponents) .addDependency( UndertowService.SERVLET_CONTAINER.append(defaultContainer), ServletContainerService.class, service.getContainer()) .addDependency(hostServiceName, Host.class, service.getHost()) .addDependency( SecurityDomainService.SERVICE_NAME.append(securityDomain), SecurityDomainContext.class, service.getSecurityDomainContextValue()) .addDependency( UndertowService.UNDERTOW, UndertowService.class, service.getUndertowService()); deploymentUnit.addToAttachmentList( Attachments.DEPLOYMENT_COMPLETE_SERVICES, deploymentServiceName); // add any dependencies required by the setup action for (final SetupAction action : setupActions) { builder.addDependencies(action.dependencies()); deploymentInfo.addThreadSetupAction( new ThreadSetupAction() { @Override public Handle setup(final HttpServerExchange exchange) { action.setup(Collections.<String, Object>emptyMap()); return new Handle() { @Override public void tearDown() { action.teardown(Collections.<String, Object>emptyMap()); } }; } }); } if (metaData.getDistributable() != null) { DistributedCacheManagerFactoryService factoryService = new DistributedCacheManagerFactoryService(); DistributedCacheManagerFactory factory = factoryService.getValue(); if (factory != null) { ServiceName factoryServiceName = deploymentServiceName.append("session"); builder.addDependency( ServiceBuilder.DependencyType.OPTIONAL, factoryServiceName, DistributedCacheManagerFactory.class, service.getDistributedCacheManagerFactoryInjectedValue()); ServiceBuilder<DistributedCacheManagerFactory> factoryBuilder = serviceTarget.addService(factoryServiceName, factoryService); boolean enabled = factory.addDeploymentDependencies( deploymentServiceName, deploymentUnit.getServiceRegistry(), serviceTarget, factoryBuilder, metaData); factoryBuilder.setInitialMode(enabled ? Mode.ON_DEMAND : Mode.NEVER).install(); } } // OSGi web applications are activated in {@link WebContextActivationProcessor} according to // bundle lifecycle changes if (deploymentUnit.hasAttachment(Attachments.OSGI_MANIFEST)) { builder.setInitialMode(Mode.NEVER); UndertowDeploymentService.ContextActivatorImpl activator = new UndertowDeploymentService.ContextActivatorImpl(builder.install()); deploymentUnit.putAttachment(ContextActivator.ATTACHMENT_KEY, activator); } else { builder.setInitialMode(Mode.ACTIVE); builder.install(); } // Process the web related mgmt information final ModelNode node = deploymentUnit.getDeploymentSubsystemModel(UndertowExtension.SUBSYSTEM_NAME); node.get(DeploymentDefinition.CONTEXT_ROOT.getName()).set("".equals(pathName) ? "/" : pathName); node.get(DeploymentDefinition.VIRTUAL_HOST.getName()).set(hostName); processManagement(deploymentUnit, metaData); }
private HttpHandler setupSecurityHandlers(HttpHandler initialHandler) { final DeploymentInfo deploymentInfo = super.getDeployment().getDeploymentInfo(); final LoginConfig loginConfig = deploymentInfo.getLoginConfig(); final Map<String, AuthenticationMechanismFactory> factoryMap = new HashMap<>(deploymentInfo.getAuthenticationMechanisms()); if (!factoryMap.containsKey(BASIC_AUTH)) { factoryMap.put(BASIC_AUTH, BasicAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(FORM_AUTH)) { factoryMap.put(FORM_AUTH, ServletFormAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(DIGEST_AUTH)) { factoryMap.put(DIGEST_AUTH, DigestAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(CLIENT_CERT_AUTH)) { factoryMap.put(CLIENT_CERT_AUTH, ClientCertAuthenticationMechanism.FACTORY); } if (!factoryMap.containsKey(ExternalAuthenticationMechanism.NAME)) { factoryMap.put(ExternalAuthenticationMechanism.NAME, ExternalAuthenticationMechanism.FACTORY); } HttpHandler current = initialHandler; current = new SSLInformationAssociationHandler(current); final SecurityPathMatches securityPathMatches = buildSecurityConstraints(); current = new ServletAuthenticationCallHandler(current); if (deploymentInfo.isDisableCachingForSecuredPages()) { current = Handlers.predicate(Predicates.authRequired(), Handlers.disableCache(current), current); } if (!securityPathMatches.isEmpty()) { current = new ServletAuthenticationConstraintHandler(current); } current = new ServletConfidentialityConstraintHandler( deploymentInfo.getConfidentialPortManager(), current); if (!securityPathMatches.isEmpty()) { current = new ServletSecurityConstraintHandler(securityPathMatches, current); } List<AuthenticationMechanism> authenticationMechanisms = new LinkedList<>(); authenticationMechanisms.add( new CachedAuthenticatedSessionMechanism()); // TODO: does this really need to be hard coded? String mechName = null; if (loginConfig != null || deploymentInfo.getJaspiAuthenticationMechanism() != null) { // we don't allow multipart requests, and always use the default encoding FormParserFactory parser = FormParserFactory.builder(false) .addParser( new FormEncodedDataDefinition() .setDefaultEncoding(deploymentInfo.getDefaultEncoding())) .build(); List<AuthMethodConfig> authMethods = Collections.<AuthMethodConfig>emptyList(); if (loginConfig != null) { authMethods = loginConfig.getAuthMethods(); } for (AuthMethodConfig method : authMethods) { AuthenticationMechanismFactory factory = factoryMap.get(method.getName()); if (factory == null) { throw UndertowServletMessages.MESSAGES.unknownAuthenticationMechanism(method.getName()); } if (mechName == null) { mechName = method.getName(); } final Map<String, String> properties = new HashMap<>(); properties.put( AuthenticationMechanismFactory.CONTEXT_PATH, deploymentInfo.getContextPath()); properties.put(AuthenticationMechanismFactory.REALM, loginConfig.getRealmName()); properties.put(AuthenticationMechanismFactory.ERROR_PAGE, loginConfig.getErrorPage()); properties.put(AuthenticationMechanismFactory.LOGIN_PAGE, loginConfig.getLoginPage()); properties.putAll(method.getProperties()); String name = method.getName().toUpperCase(Locale.US); // The mechanism name is passed in from the HttpServletRequest interface as the name // reported needs to be // comparable using '==' name = name.equals(FORM_AUTH) ? FORM_AUTH : name; name = name.equals(BASIC_AUTH) ? BASIC_AUTH : name; name = name.equals(DIGEST_AUTH) ? DIGEST_AUTH : name; name = name.equals(CLIENT_CERT_AUTH) ? CLIENT_CERT_AUTH : name; authenticationMechanisms.add(factory.create(name, parser, properties)); } } ((DeploymentImpl) super.getDeployment()).setAuthenticationMechanisms(authenticationMechanisms); // if the JASPI auth mechanism is set then it takes over if (deploymentInfo.getJaspiAuthenticationMechanism() == null) { current = new AuthenticationMechanismsHandler(current, authenticationMechanisms); } else { current = new AuthenticationMechanismsHandler( current, Collections.<AuthenticationMechanism>singletonList( deploymentInfo.getJaspiAuthenticationMechanism())); } current = new CachedAuthenticatedSessionHandler(current, super.getDeployment().getServletContext()); List<NotificationReceiver> notificationReceivers = deploymentInfo.getNotificationReceivers(); if (!notificationReceivers.isEmpty()) { current = new NotificationReceiverHandler(current, notificationReceivers); } // TODO - A switch to constraint driven could be configurable, however before we can support // that with servlets we would // need additional tracking within sessions if a servlet has specifically requested that // authentication occurs. SecurityContextFactory contextFactory = deploymentInfo.getSecurityContextFactory(); if (contextFactory == null) { contextFactory = SecurityContextFactoryImpl.INSTANCE; } current = new SecurityInitialHandler( AuthenticationMode.PRO_ACTIVE, deploymentInfo.getIdentityManager(), mechName, contextFactory, current); return current; }
@Override public String getContextPath() { return deploymentInfo.getContextPath(); }