com.bcknds.demo.oauth2.security.ClientCredentialAuthenticationTests.java Source code

Java tutorial

Introduction

Here is the source code for com.bcknds.demo.oauth2.security.ClientCredentialAuthenticationTests.java

Source

/**
 * Copyright 2014 Michael Brush
 * 
 * Licensed 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 com.bcknds.demo.oauth2.security;

import org.junit.Before;
import org.junit.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidScopeException;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import com.bcknds.demo.oauth2.BaseTest;
import com.bcknds.demo.oauth2.util.AuthenticationUtil;
import com.bcknds.demo.oauth2.util.SSLCertificateValidation;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

/**
 * Authentication Tests for Client Credentials
 * 
 * In this class I did not use @Test( expected = SomeException.class ) for two reasons
 *   1.) This will show how exception can be handled
 *   2.) OAuth2RestTemplate returns a generic OAuth2AccessDeniedException, but the cause underneath
 *       holds the real value for the failure.
 * 
 * @author Michael Brush
 */
public class ClientCredentialAuthenticationTests extends BaseTest {

    @Before
    public void setUp() {
        SSLCertificateValidation.disable();
    }

    /**
     * Verify that authentication is successful.
     */
    @Test
    public void testSuccessfulAuthentication() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentials();
        OAuth2AccessToken token = null;
        try {
            token = restTemplate.getAccessToken();
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(ex.getMessage());
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
        assertNotNull(token.getValue());
    }

    /**
     * This test is designed to test having a bad client Id.
     */
    @Test
    public void testBadClientId() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentialsWithBadClientId();
        try {
            restTemplate.getAccessToken();
            fail("Expected OAuth2AccessDeniedException, but none was thrown");
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof HttpClientErrorException) {
                HttpClientErrorException clientException = (HttpClientErrorException) ex.getCause();
                assertEquals(HttpStatus.UNAUTHORIZED, clientException.getStatusCode());
            } else if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(String.format("Expected HttpClientErrorException. Got %s",
                        ex.getCause().getClass().getName()));
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * This test is designed to test having a bad secret.
     */
    @Test
    public void testBadClientSecret() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentialsWithBadSecret();
        try {
            restTemplate.getAccessToken();
            fail("Expected OAuth2AccessDeniedException, but none was thrown");
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof OAuth2Exception) {
                OAuth2Exception clientException = (OAuth2Exception) ex.getCause();
                assertEquals(HttpStatus.BAD_REQUEST.value(), clientException.getHttpErrorCode());
            } else if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(String.format("Expected HttpClientErrorException. Got %s",
                        ex.getCause().getClass().getName()));
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * This test is designed to test having a bad scope.
     */
    @Test
    public void testBadScope() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentialsWithBadScope();
        try {
            restTemplate.getAccessToken();
            fail("Expected OAuth2AccessDeniedException, but none was thrown");
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof InvalidScopeException) {
                InvalidScopeException clientException = (InvalidScopeException) ex.getCause();
                assertEquals(HttpStatus.BAD_REQUEST.value(), clientException.getHttpErrorCode());
            } else if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(String.format("Expected HttpClientErrorException. Got %s",
                        ex.getCause().getClass().getName()));
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test insecure endpoint without authentication
     */
    @Test
    public void testInsecureEndpointNoAuthentication() {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(INSECURE_ENDPOINT, String.class);
            assertEquals("You are home.", response.getBody());
            assertEquals(HttpStatus.OK, response.getStatusCode());
        } catch (ResourceAccessException ex) {
            fail("It appears that the server may not be running. Please start it before running tests");
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test insecure endpoint with authentication
     */
    @Test
    public void testInsecureEndpoint() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentials();
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(INSECURE_ENDPOINT, String.class);
            assertEquals("You are home.", response.getBody());
            assertEquals(HttpStatus.OK, response.getStatusCode());
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(ex.getMessage());
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test secure endpoint without authentication
     */
    @Test
    public void testSecureEndpointNoAuthentication() {
        RestTemplate restTemplate = new RestTemplate();
        try {
            restTemplate.getForEntity(SECURE_ENDPOINT, String.class);
            fail("Exception expected. None was thrown.");
        } catch (HttpClientErrorException ex) {
            assertEquals(ex.getStatusCode(), HttpStatus.UNAUTHORIZED);
        } catch (ResourceAccessException ex) {
            fail("It appears that the server may not be running. Please start it before running tests");
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test secure endpoint with authentication
     */
    @Test
    public void testSecureEndpoint() {
        // Test while logged in.
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentials();
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(SECURE_ENDPOINT, String.class);
            assertEquals("You are a VIP since you have secure access.", response.getBody());
            assertEquals(HttpStatus.OK, response.getStatusCode());
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(ex.getMessage());
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test successful authentication to method secure endpoint that requires only authentication
     * using client credentials
     */
    @Test
    public void testClientCredentialsMethodEndpoint() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentials();
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(METHOD_SECURE_ENDPOINT, String.class);
            assertEquals("This is secured by annotation", response.getBody());
            assertEquals(HttpStatus.OK, response.getStatusCode());
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof ResourceAccessException) {
                fail("It appears that the server may not be running. Please start it before running tests");
            } else {
                fail(ex.getMessage());
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test authentication failure to method secure endpoint that requires only authentication
     * using no authentication
     */
    @Test
    public void testClientCredentialsMethodNotLoggedIn() {
        RestTemplate restTemplate = new RestTemplate();
        try {
            restTemplate.getForEntity(METHOD_SECURE_ENDPOINT, String.class);
            fail("Expected exception. None was thrown.");
        } catch (HttpClientErrorException ex) {
            assertEquals(ex.getStatusCode(), HttpStatus.UNAUTHORIZED);
        } catch (ResourceAccessException ex) {
            fail("It appears that the server may not be running. Please start it before running tests");
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test authentication failure to role secure endpoint that requires the ROLE_PASSWORD role
     * which the client credentials client does not have
     */
    @Test
    public void testClientCredentialsInvalidRole() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getClientCredentials();
        try {
            restTemplate.getForEntity(ROLE_SECURE_ENDPOINT, String.class);
            fail("Expected exception. None was thrown");
        } catch (UserDeniedAuthorizationException ex) {
            assertEquals(HttpStatus.BAD_REQUEST.value(), ex.getHttpErrorCode());
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }
}