Java tutorial
/** * 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()); } } }