/* * JBoss, Home of Professional Open Source. * Copyright (c) 2015, Red Hat, Inc., and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.as.test.integration.web.security.digest; import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.as.arquillian.api.ServerSetup; import org.jboss.as.arquillian.api.ServerSetupTask; import org.jboss.as.arquillian.container.ManagementClient; import org.jboss.as.test.integration.management.util.CLIWrapper; import org.jboss.as.test.integration.security.WebSecurityPasswordBasedBase; import org.jboss.as.test.integration.security.common.AbstractSecurityDomainsServerSetupTask; import org.jboss.as.test.integration.security.common.Utils; import org.jboss.as.test.integration.security.common.config.SecurityDomain; import org.jboss.as.test.integration.security.common.config.SecurityModule; import org.jboss.as.test.integration.security.common.servlets.SimpleSecuredServlet; import org.jboss.as.test.integration.security.common.servlets.SimpleServlet; import org.jboss.as.test.integration.web.security.WebSecurityCommon; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.Test; import org.junit.runner.RunWith; import org.wildfly.test.security.common.elytron.PropertyFileBasedDomain; import org.wildfly.test.security.common.elytron.UndertowDomainMapper; import org.wildfly.test.security.common.elytron.UserWithRoles; /** * Simple test case for web DIGEST authentication. * * @author olukas */ @RunWith(Arquillian.class) @ServerSetup({WebSecurityDIGESTTestCase.WebSecurityDigestSecurityDomainSetup.class}) @RunAsClient public class WebSecurityDIGESTTestCase extends WebSecurityPasswordBasedBase { private static final String SECURITY_DOMAIN_NAME = "digestSecurityDomain"; private static final String DEPLOYMENT = "digestApp"; private static final String GOOD_USER_NAME = "anil"; private static final String GOOD_USER_PASSWORD = "anil"; private static final String GOOD_USER_ROLE = SimpleSecuredServlet.ALLOWED_ROLE; private static final String SUPER_USER_NAME = "marcus"; private static final String SUPER_USER_PASSWORD = "marcus"; private static final String SUPER_USER_ROLE = "superuser"; private static final String WEB_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "\n" + "<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun" + ".com/xml/ns/javaee/web-app_3_0.xsd\"\n" + " version=\"3.0\">\n" + "\n" + "\t<login-config>\n" + "\t\t<auth-method>DIGEST</auth-method>\n" + "\t\t<realm-name>" + SECURITY_DOMAIN_NAME + "</realm-name>\n" + "\t</login-config>\n" + "</web-app>"; @Deployment(name = DEPLOYMENT) public static WebArchive deployment() throws Exception { final WebArchive war = ShrinkWrap.create(WebArchive.class, DEPLOYMENT + ".war"); war.addClasses(SimpleServlet.class, SimpleSecuredServlet.class); war.addAsWebInfResource(Utils.getJBossWebXmlAsset(SECURITY_DOMAIN_NAME), "jboss-web.xml"); war.addAsWebInfResource(new StringAsset(WEB_XML), "web.xml"); return war; } @ArquillianResource private URL url; /** * Check whether user with incorrect credentials has not access to secured page. * * @param url * @throws Exception */ @OperateOnDeployment(DEPLOYMENT) @Test public void testWrongUser(@ArquillianResource URL url) throws Exception { makeCall(GOOD_USER_NAME, GOOD_USER_PASSWORD + "makeThisPasswordWrong", HTTP_UNAUTHORIZED); } @Override protected void makeCall(String user, String pass, int expectedCode) throws Exception { final URL servletUrl = new URL(url.toExternalForm() + SimpleSecuredServlet.SERVLET_PATH.substring(1)); Utils.makeCallWithBasicAuthn(servletUrl, user, pass, expectedCode); } static class WebSecurityDigestSecurityDomainSetup implements ServerSetupTask { private LegacySecurityDomainsSetup secDomainSetup; private CLIWrapper cli; private PropertyFileBasedDomain ps; private UndertowDomainMapper domainMapper; @Override public void setup(ManagementClient managementClient, String s) throws Exception { if (WebSecurityCommon.isElytron()) { cli = new CLIWrapper(true); setupElytronBasedSecurityDomain(); } else { secDomainSetup = new LegacySecurityDomainsSetup(); secDomainSetup.setup(managementClient, s); } } @Override public void tearDown(ManagementClient managementClient, String s) throws Exception { if (WebSecurityCommon.isElytron()) { domainMapper.remove(cli); ps.remove(cli); cli.close(); } else { secDomainSetup.tearDown(managementClient, s); } } private void setupElytronBasedSecurityDomain() throws Exception { ps = PropertyFileBasedDomain.builder() .withUser(GOOD_USER_NAME, GOOD_USER_PASSWORD, GOOD_USER_ROLE) .withUser(SUPER_USER_NAME, SUPER_USER_PASSWORD, SUPER_USER_ROLE) .withName(SECURITY_DOMAIN_NAME).build(); ps.create(cli); domainMapper = UndertowDomainMapper.builder().withName(SECURITY_DOMAIN_NAME).build(); domainMapper.create(cli); } } static class LegacySecurityDomainsSetup extends AbstractSecurityDomainsServerSetupTask { @Override protected SecurityDomain[] getSecurityDomains() throws Exception { List<UserWithRoles> userWithRoles = new ArrayList<UserWithRoles>(); userWithRoles.add(UserWithRoles.builder().withName(GOOD_USER_NAME).withPassword(GOOD_USER_PASSWORD) .withRoles(GOOD_USER_ROLE).build()); userWithRoles.add(UserWithRoles.builder().withName(SUPER_USER_NAME).withPassword(SUPER_USER_PASSWORD) .withRoles(SUPER_USER_ROLE).build()); WebSecurityCommon.PropertyFiles propFiles = WebSecurityCommon.createPropertiesFiles(userWithRoles, SECURITY_DOMAIN_NAME); final Map<String, String> lmOptions = new HashMap<>(); lmOptions.put("hashAlgorithm", "MD5"); lmOptions.put("hashEncoding", "RFC2617"); lmOptions.put("hashUserPassword", "false"); lmOptions.put("hashStorePassword", "true"); lmOptions.put("passwordIsA1Hash", "false"); lmOptions.put("storeDigestCallback", "org.jboss.security.auth.callback.RFC2617Digest"); lmOptions.put("usersProperties", propFiles.getUsers().getAbsolutePath()); lmOptions.put("rolesProperties", propFiles.getRoles().getAbsolutePath()); final SecurityDomain sd1 = new SecurityDomain.Builder() .name(SECURITY_DOMAIN_NAME) .loginModules(new SecurityModule.Builder() .name("UsersRoles") .options(lmOptions) .build()) .build(); return new SecurityDomain[]{sd1}; } } }