org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML1BearerGrantHandlerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.oauth2.token.handlers.grant.saml.SAML1BearerGrantHandlerTest.java

Source

/*
 * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.wso2.carbon.identity.oauth2.token.handlers.grant.saml;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.opensaml.DefaultBootstrap;
import org.opensaml.security.SAMLSignatureProfileValidator;
import org.powermock.reflect.internal.WhiteboxImpl;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.base.api.ServerConfigurationService;
import org.wso2.carbon.core.internal.CarbonCoreDataHolder;
import org.wso2.carbon.core.util.KeyStoreManager;
import org.wso2.carbon.identity.common.testng.WithAxisConfiguration;
import org.wso2.carbon.identity.common.testng.WithCarbonHome;
import org.wso2.carbon.identity.common.testng.WithH2Database;
import org.wso2.carbon.identity.common.testng.WithRealmService;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.oauth2.TestConstants;
import org.wso2.carbon.identity.oauth2.dto.OAuth2AccessTokenReqDTO;
import org.wso2.carbon.identity.oauth2.model.RequestParameter;
import org.wso2.carbon.identity.oauth2.token.OAuthTokenReqMessageContext;
import org.wso2.carbon.identity.testutil.powermock.PowerMockIdentityBaseTest;
import org.wso2.carbon.idp.mgt.internal.IdpMgtServiceComponentHolder;
import org.wso2.carbon.registry.core.service.RegistryService;
import org.wso2.carbon.user.core.service.RealmService;
import org.wso2.carbon.user.core.tenant.TenantManager;

import java.io.ByteArrayInputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertTrue;
import static org.testng.AssertJUnit.assertEquals;

@WithCarbonHome
@WithH2Database(files = { "dbScripts/idp.sql" })
@WithAxisConfiguration
@WithRealmService(tenantDomain = TestConstants.TENANT_DOMAIN, initUserStoreManager = true)
public class SAML1BearerGrantHandlerTest extends PowerMockIdentityBaseTest {

    private SAML1BearerGrantHandler saml1BearerGrantHandler;
    private static final String ISSUER1 = "idp1";
    private static final String ISSUER2 = "LOCAL";
    private static final String NOT_ON_OR_AFTER1 = "2002-06-19T17:10:37.795Z";
    private static final String NOT_ON_OR_AFTER2 = new DateTime().toString();

    private static final String CERTIFICATE = "MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJVUzELMAkGA1UE\n"
            + "CAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoMBFdTTzIxEjAQBgNVBAMMCWxv\n"
            + "Y2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAyMTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQsw\n"
            + "CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UE\n"
            + "AwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTou\n"
            + "sMzOM4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5\n"
            + "HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQID\n"
            + "AQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEAW5wPR7cr1LAdq+IrR44i\n"
            + "QlRG5ITCZXY9hI0PygLP2rHANh+PYfTmxbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJR\n"
            + "O4d1DeGHT/YnIjs9JogRKv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=";

    private static String assertion = "  <saml:Assertion\n"
            + "    xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\"\n"
            + "    MajorVersion=\"1\" MinorVersion=\"1\"\n" + "    AssertionID=\"buGxcG4gILg5NlocyLccDz6iXrUa\"\n"
            + "    Issuer=\"" + ISSUER1 + "\"\n" + "    IssueInstant=\"2002-06-19T17:05:37.795Z\">\n"
            + "    <saml:Conditions\n" + "      NotBefore=\"2002-06-19T17:00:37.795Z\"\n" + "      NotOnOrAfter=\""
            + NOT_ON_OR_AFTER1 + "\">\n" + "      <saml:AudienceRestrictionCondition>\n"
            + "           <saml:Audience>https://sp.example.com/samlsso</saml:Audience>\n"
            + "      </saml:AudienceRestrictionCondition>\n" + "    </saml:Conditions>\n"
            + "    <saml:AuthenticationStatement\n"
            + "      AuthenticationMethod=\"urn:oasis:names:tc:SAML:1.0:am:password\"\n"
            + "      AuthenticationInstant=\"2002-06-19T17:05:17.706Z\">\n" + "      <saml:Subject>\n"
            + "        <saml:NameIdentifier\n"
            + "          Format=\"urn:oasis:names:tc:SAML:1.0:assertion#emailAddress\">\n" + "          user@"
            + ISSUER1 + "\n" + "        </saml:NameIdentifier>\n" + "        <saml:SubjectConfirmation>\n"
            + "          <saml:ConfirmationMethod>\n" + "            urn:oasis:names:tc:SAML:1.0:cm:bearer\n"
            + "          </saml:ConfirmationMethod>\n" + "        </saml:SubjectConfirmation>\n"
            + "      </saml:Subject>\n" + "    </saml:AuthenticationStatement>\n"
            + "    <ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n"
            + "            <ds:SignedInfo>\n"
            + "                <ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />\n"
            + "                <ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" />\n"
            + "                <ds:Reference URI=\"#buGxcG4gILg5NlocyLccDz6iXrUa\">\n"
            + "                    <ds:Transforms>\n"
            + "                        <ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\" />\n"
            + "                        <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />\n"
            + "                    </ds:Transforms>\n"
            + "                    <ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />\n"
            + "                    <ds:DigestValue>FNB5TA/klWcRpdAIx4sBaANSnsg=</ds:DigestValue>\n"
            + "                </ds:Reference>\n" + "            </ds:SignedInfo>\n"
            + "            <ds:SignatureValue>\n"
            + "               kRL6SR/6zWqmndMzgsSaOwPNqXpgIZ193PcHBto5tYtOwKMpDs0dgpS/79h+jwuhZxVfuZ9U64gB\n"
            + "               uwBfE3xjALYutF7f20aWQ9E3s7tWyI81RxLU6LtyyFveUCcRAzqvEfPu8w4qqOITJvl3zlTIBJ9x\n"
            + "               d+Y4cWt54SmI66XT54g=\n" + "            </ds:SignatureValue>\n"
            + "           <ds:KeyInfo>\n" + "            <ds:X509Data>\n" + "                <ds:X509Certificate>"
            + CERTIFICATE + "                </ds:X509Certificate>\n" + "            </ds:X509Data>\n"
            + "        </ds:KeyInfo>\n" + "    </ds:Signature>" + "  </saml:Assertion>";

    @BeforeMethod
    public void setUp() throws Exception {
        saml1BearerGrantHandler = new SAML1BearerGrantHandler();
    }

    @Test
    public void testInit() throws Exception {
        saml1BearerGrantHandler = spy(saml1BearerGrantHandler);
        saml1BearerGrantHandler.init();
        verify(saml1BearerGrantHandler).init();
    }

    @DataProvider(name = "BuildAssertion")
    public static Object[][] buildAssertion() {
        return new Object[][] { { StringUtils.EMPTY, false, false }, { assertion, false, false },
                { assertion.replace(ISSUER1, ISSUER2), false, false }, { StringUtils.EMPTY, true, false },
                { assertion, true, false }, { assertion.replace(ISSUER1, ISSUER2), true, false },

                { StringUtils.EMPTY, false, false },
                { assertion.replace(NOT_ON_OR_AFTER1, NOT_ON_OR_AFTER2), false, false },
                { (assertion.replace(NOT_ON_OR_AFTER1, NOT_ON_OR_AFTER2)).replace(ISSUER1, ISSUER2), false, false },
                { StringUtils.EMPTY, true, false },
                { assertion.replace(NOT_ON_OR_AFTER1, NOT_ON_OR_AFTER2), true, false },
                { (assertion.replace(NOT_ON_OR_AFTER1, NOT_ON_OR_AFTER2)).replace(ISSUER1, ISSUER2), true,
                        false } };
    }

    @Test(dataProvider = "BuildAssertion")
    public void testValidateGrant(String assertion, boolean enableAudienceRestriction, boolean expectedResult)
            throws Exception {
        OAuthTokenReqMessageContext oAuthTokenReqMessageContext = buildOAuth2AccessTokenReqDTO();
        RequestParameter[] requestParameters = new RequestParameter[] {
                new RequestParameter("assertion", Base64.encodeBase64String(assertion.getBytes())) };
        DefaultBootstrap.bootstrap();
        oAuthTokenReqMessageContext.getOauth2AccessTokenReqDTO().setRequestParameters(requestParameters);
        WhiteboxImpl.setInternalState(saml1BearerGrantHandler, "audienceRestrictionValidationEnabled",
                enableAudienceRestriction);
        RealmService realmService = mock(RealmService.class);
        RegistryService registryService = mock(RegistryService.class);
        ServerConfigurationService serverConfigurationService = mock(ServerConfigurationService.class);
        CarbonCoreDataHolder.getInstance().setRegistryService(registryService);
        CarbonCoreDataHolder.getInstance().setServerConfigurationService(serverConfigurationService);
        TenantManager tenantManager = mock(TenantManager.class);
        when(realmService.getTenantManager()).thenReturn(tenantManager);
        when(tenantManager.getTenantId(TestConstants.CARBON_TENANT_DOMAIN))
                .thenReturn(MultitenantConstants.SUPER_TENANT_ID);
        IdpMgtServiceComponentHolder.getInstance().setRealmService(realmService);
        KeyStoreManager keyStoreManager = mock(KeyStoreManager.class);
        ConcurrentHashMap<String, KeyStoreManager> mtKeyStoreManagers = new ConcurrentHashMap();
        mtKeyStoreManagers.put("-1234", keyStoreManager);
        WhiteboxImpl.setInternalState(KeyStoreManager.class, "mtKeyStoreManagers", mtKeyStoreManagers);
        X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X.509")
                .generateCertificate(new ByteArrayInputStream(Base64.decodeBase64(CERTIFICATE)));
        when(keyStoreManager.getDefaultPrimaryCertificate()).thenReturn(cert);
        Map<String, Object> configuration = new HashMap<>();
        configuration.put("SSOService.EntityId", "LOCAL");
        WhiteboxImpl.setInternalState(IdentityUtil.class, "configuration", configuration);
        saml1BearerGrantHandler.profileValidator = new SAMLSignatureProfileValidator();
        assertEquals(saml1BearerGrantHandler.validateGrant(oAuthTokenReqMessageContext), expectedResult);
        WhiteboxImpl.setInternalState(IdentityUtil.class, "configuration", new HashMap<>());
    }

    @Test
    public void testValidateScope() throws Exception {
        assertTrue(saml1BearerGrantHandler.validateScope(buildOAuth2AccessTokenReqDTO()));
    }

    @Test
    public void testAuthorizeAccessDelegation() throws Exception {
        assertTrue(saml1BearerGrantHandler.authorizeAccessDelegation(buildOAuth2AccessTokenReqDTO()));
    }

    @Test
    public void testIssueRefreshToken() throws Exception {
        assertTrue(saml1BearerGrantHandler.issueRefreshToken());
    }

    private OAuthTokenReqMessageContext buildOAuth2AccessTokenReqDTO() {
        OAuth2AccessTokenReqDTO oAuth2AccessTokenReqDTO = new OAuth2AccessTokenReqDTO();
        OAuthTokenReqMessageContext oAuthTokenReqMessageContext = new OAuthTokenReqMessageContext(
                oAuth2AccessTokenReqDTO);
        return oAuthTokenReqMessageContext;
    }

}