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

Java tutorial

Introduction

Here is the source code for com.bcknds.demo.oauth2.security.PasswordAuthenticationTests.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 java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
import org.springframework.web.client.ResourceAccessException;

import com.bcknds.demo.oauth2.BaseTest;
import com.bcknds.demo.oauth2.model.Role;
import com.bcknds.demo.oauth2.model.User;
import com.bcknds.demo.oauth2.service.RoleService;
import com.bcknds.demo.oauth2.service.UserService;
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 Password Authentication
 * 
 * This class does not do scope or client id failures since ClientCredentialAuthenticationTests cover those
 * 
 * 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 PasswordAuthenticationTests extends BaseTest {

    private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    private User validUser = new User("user", encoder.encode("password"));
    private Role validRole = new Role("ROLE_PASSWORD");

    @Before
    public void setUp() {
        SSLCertificateValidation.disable();
        validRole = roleService.save(validRole);
        validUser.addRole(validRole);
        validUser = userService.save(validUser);
    }

    @After
    public void tearDown() {
        userService.remove(validUser);
        roleService.remove(validRole);
    }

    /**
     * Verify that authentication is successful.
     */
    @Test
    public void testSuccessfulAuthentication() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, PASSWORD);
        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());
    }

    /**
     * Test using a bad username
     */
    @Test
    public void testBadUsername() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials("badUsername", PASSWORD);
        try {
            restTemplate.getAccessToken();
            fail("Expected OAuth2AccessDeniedException, but none was thrown");
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof InvalidGrantException) {
                InvalidGrantException clientException = (InvalidGrantException) 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 InvalidGrantException. Got %s", ex.getCause().getClass().getName()));
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test using a bad username
     */
    @Test
    public void testBadPassword() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, "badPassword");
        try {
            restTemplate.getAccessToken();
            fail("Expected OAuth2AccessDeniedException, but none was thrown");
        } catch (OAuth2AccessDeniedException ex) {
            if (ex.getCause() instanceof InvalidGrantException) {
                InvalidGrantException clientException = (InvalidGrantException) 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 InvalidGrantException. Got %s", ex.getCause().getClass().getName()));
            }
        } catch (Exception ex) {
            fail(ex.getMessage());
        }
    }

    /**
     * Test successful authentication to method secure endpoint that requires only authentication
     * using password authentication
     */
    @Test
    public void testPasswordAuthenticationMethodEndpoint() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, PASSWORD);
        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 successful authentication to method secure endpoint that requires the ROLE_PASSWORD
     * role.
     */
    @Test
    public void testPasswordAuthenticationRoleEndpoint() {
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, PASSWORD);
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(ROLE_SECURE_ENDPOINT, String.class);
            assertEquals("This is secured by annotation and role.", 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 role secure endpoint that requires the ROLE_PASSWORD role
     * which this user will not have
     */
    @Test
    public void testPasswordAuthenticationBadRole() {
        userService.remove(validUser);
        Role badRole = new Role("ROLE_INVALID");
        validUser.setRoles(new ArrayList<Role>());
        validUser.addRole(badRole);
        userService.save(validUser);
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, PASSWORD);
        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());
        }
    }

    /**
     * Test successful authentication to method secure endpoint that requires the ROLE_PASSWORD
     * role.
     */
    @Test
    public void testPasswordAuthenticationMultipleRole() {
        Role adminRole = new Role("ROLE_ADMIN");
        userService.remove(validUser);
        validUser.addRole(adminRole);
        userService.save(validUser);
        OAuth2RestTemplate restTemplate = AuthenticationUtil.getPasswordCredentials(USERNAME, PASSWORD);
        ResponseEntity<String> response = null;
        try {
            response = restTemplate.getForEntity(ROLE_SECURE_ENDPOINT, String.class);
            assertEquals("This is secured by annotation and role.", 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());
        }
    }
}