Search in sources :

Example 1 with CrossSiteRequestForgeryException

use of uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException in project isaac-api by isaacphysics.

the class UserAuthenticationManager method ensureNoCSRF.

/**
 * Verify with the request that there is no CSRF violation.
 *
 * @param request
 *            - http request to verify there is no CSRF
 * @param oauthProvider
 *            -
 * @return true if we are happy , false if we think a violation has occurred.
 * @throws CrossSiteRequestForgeryException
 *             - if we suspect cross site request forgery.
 */
private boolean ensureNoCSRF(final HttpServletRequest request, final IOAuthAuthenticator oauthProvider) throws CrossSiteRequestForgeryException {
    Validate.notNull(request);
    String key;
    if (oauthProvider instanceof IOAuth2Authenticator) {
        key = STATE_PARAM_NAME;
    } else if (oauthProvider instanceof IOAuth1Authenticator) {
        key = OAUTH_TOKEN_PARAM_NAME;
    } else {
        throw new CrossSiteRequestForgeryException("Provider not recognized.");
    }
    // to deal with cross site request forgery
    String csrfTokenFromUser = (String) request.getSession().getAttribute(key);
    String csrfTokenFromProvider = request.getParameter(key);
    if (null == csrfTokenFromUser || !csrfTokenFromUser.equals(csrfTokenFromProvider)) {
        log.error("Invalid state parameter - Provider said: " + request.getParameter(STATE_PARAM_NAME) + " Session said: " + request.getSession().getAttribute(STATE_PARAM_NAME));
        return false;
    } else {
        log.debug("State parameter matches - Provider said: " + request.getParameter(STATE_PARAM_NAME) + " Session said: " + request.getSession().getAttribute(STATE_PARAM_NAME));
        return true;
    }
}
Also used : IOAuth1Authenticator(uk.ac.cam.cl.dtg.segue.auth.IOAuth1Authenticator) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) IOAuth2Authenticator(uk.ac.cam.cl.dtg.segue.auth.IOAuth2Authenticator)

Example 2 with CrossSiteRequestForgeryException

use of uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException in project isaac-api by isaacphysics.

the class AuthenticationFacade method authenticationCallback.

/**
 * This is the callback url that auth providers should use to send us information about users.
 *
 * @param request
 *            - http request from user
 * @param response
 *            to tell the browser to store the session in our own segue cookie if successful.
 * @param signinProvider
 *            - requested signing provider string
 * @return Redirect response to send the user to the home page.
 */
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{provider}/callback")
@ApiOperation(value = "SSO callback URL for a given provider.")
public final Response authenticationCallback(@Context final HttpServletRequest request, @Context final HttpServletResponse response, @PathParam("provider") final String signinProvider) {
    try {
        // TODO - review if rememberMe should default to true for SSO logins:
        RegisteredUserDTO userToReturn = userManager.authenticateCallback(request, response, signinProvider, true);
        this.getLogManager().logEvent(userToReturn, request, SegueServerLogType.LOG_IN, Maps.newHashMap());
        return Response.ok(userToReturn).build();
    } catch (IOException e) {
        SegueErrorResponse error = new SegueErrorResponse(Status.INTERNAL_SERVER_ERROR, "Exception while trying to authenticate a user" + " - during callback step.", e);
        log.error(error.getErrorMessage(), e);
        return error.toResponse();
    } catch (NoUserException e) {
        SegueErrorResponse error = new SegueErrorResponse(Status.UNAUTHORIZED, "Unable to locate user information.");
        log.error("No userID exception received. Unable to locate user.", e);
        return error.toResponse();
    } catch (AuthenticationCodeException | CrossSiteRequestForgeryException | AuthenticatorSecurityException | CodeExchangeException e) {
        SegueErrorResponse error = new SegueErrorResponse(Status.UNAUTHORIZED, e.getMessage());
        log.info("Error detected during authentication: " + e.getClass().toString());
        return error.toResponse();
    } catch (DuplicateAccountException e) {
        log.debug("Duplicate user already exists in the database.", e);
        return new SegueErrorResponse(Status.FORBIDDEN, e.getMessage()).toResponse();
    } catch (AccountAlreadyLinkedException e) {
        log.error("Internal Database error during authentication", e);
        return new SegueErrorResponse(Status.BAD_REQUEST, "The account you are trying to link is already attached to a user of this system.").toResponse();
    } catch (SegueDatabaseException e) {
        log.error("Internal Database error during authentication", e);
        return new SegueErrorResponse(Status.INTERNAL_SERVER_ERROR, "Internal database error during authentication.").toResponse();
    } catch (AuthenticationProviderMappingException e) {
        return new SegueErrorResponse(Status.BAD_REQUEST, "Unable to map to a known authenticator. The provider: " + signinProvider + " is unknown").toResponse();
    }
}
Also used : AuthenticationCodeException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationCodeException) NoUserException(uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserException) SegueDatabaseException(uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) IOException(java.io.IOException) DuplicateAccountException(uk.ac.cam.cl.dtg.segue.auth.exceptions.DuplicateAccountException) AccountAlreadyLinkedException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AccountAlreadyLinkedException) SegueErrorResponse(uk.ac.cam.cl.dtg.isaac.dto.SegueErrorResponse) RegisteredUserDTO(uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO) AuthenticatorSecurityException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticatorSecurityException) CodeExchangeException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CodeExchangeException) AuthenticationProviderMappingException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationProviderMappingException) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) ApiOperation(io.swagger.annotations.ApiOperation)

Example 3 with CrossSiteRequestForgeryException

use of uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException in project isaac-api by isaacphysics.

the class UserManagerTest method authenticateCallback_checkWhenNoCSRFProvided_throwsCSRFException.

/**
 * Verify that a bad (null) CSRF response from the authentication provider causes an error response.
 */
@Test
public final void authenticateCallback_checkWhenNoCSRFProvided_throwsCSRFException() {
    UserAccountManager userManager = buildTestUserManager();
    // method param setup for method under test
    HttpSession dummySession = createMock(HttpSession.class);
    HttpServletRequest request = createMock(HttpServletRequest.class);
    HttpServletResponse response = createMock(HttpServletResponse.class);
    String validOAuthProvider = "test";
    expect(request.getSession()).andReturn(dummySession).atLeastOnce();
    expect(dummySession.getAttribute(Constants.SESSION_USER_ID)).andReturn(null).anyTimes();
    // Mock URL params extract stuff
    expect(request.getQueryString()).andReturn("").atLeastOnce();
    // Mock CSRF checks
    expect(dummySession.getAttribute(Constants.STATE_PARAM_NAME)).andReturn(null).atLeastOnce();
    expect(request.getParameter(Constants.STATE_PARAM_NAME)).andReturn(CSRF_TEST_VALUE).atLeastOnce();
    replay(dummySession);
    replay(request);
    replay(dummyQuestionDatabase);
    // Act
    try {
        userManager.authenticateCallback(request, response, validOAuthProvider, false);
        fail("Exception should have been thrown");
    } catch (CrossSiteRequestForgeryException e) {
    // pass
    } catch (Exception e) {
    // not interested in this case.
    }
    // Assert
    verify(dummyQuestionDatabase, dummySession, request);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpSession(javax.servlet.http.HttpSession) HttpServletResponse(javax.servlet.http.HttpServletResponse) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) AuthenticationProviderMappingException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationProviderMappingException) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) NoUserLoggedInException(uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserLoggedInException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) Test(org.junit.Test)

Example 4 with CrossSiteRequestForgeryException

use of uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException in project isaac-api by isaacphysics.

the class UserManagerTest method authenticateCallback_checkInvalidCSRF_throwsCSRFException.

/**
 * Verify that a bad CSRF response from the authentication provider causes an error response.
 */
@Test
public final void authenticateCallback_checkInvalidCSRF_throwsCSRFException() {
    UserAccountManager userManager = buildTestUserManager();
    HttpSession dummySession = createMock(HttpSession.class);
    HttpServletRequest request = createMock(HttpServletRequest.class);
    HttpServletResponse response = createMock(HttpServletResponse.class);
    String someInvalidCSRFValue = "FRAUDHASHAPPENED";
    String validOAuthProvider = "test";
    expect(request.getSession()).andReturn(dummySession).atLeastOnce();
    expect(dummySession.getAttribute(Constants.SESSION_USER_ID)).andReturn(null).anyTimes();
    // Mock URL params extract stuff
    // Return any non-null string
    String queryString = Constants.STATE_PARAM_NAME + "=" + someInvalidCSRFValue;
    expect(request.getQueryString()).andReturn(queryString).once();
    // Mock CSRF checks
    expect(dummySession.getAttribute(Constants.STATE_PARAM_NAME)).andReturn(CSRF_TEST_VALUE).atLeastOnce();
    expect(request.getParameter(Constants.STATE_PARAM_NAME)).andReturn(someInvalidCSRFValue).atLeastOnce();
    replay(dummySession, request, dummyQuestionDatabase);
    // Act
    try {
        userManager.authenticateCallback(request, response, validOAuthProvider, false);
        fail("Exception should have been thrown");
    } catch (CrossSiteRequestForgeryException e) {
    // success
    } catch (Exception e) {
    // not interested in these cases.
    }
    // Assert
    verify(dummyQuestionDatabase, dummySession, request);
}
Also used : HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpSession(javax.servlet.http.HttpSession) HttpServletResponse(javax.servlet.http.HttpServletResponse) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) AuthenticationProviderMappingException(uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationProviderMappingException) CrossSiteRequestForgeryException(uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException) NoUserLoggedInException(uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserLoggedInException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) Test(org.junit.Test)

Aggregations

CrossSiteRequestForgeryException (uk.ac.cam.cl.dtg.segue.auth.exceptions.CrossSiteRequestForgeryException)4 IOException (java.io.IOException)3 AuthenticationProviderMappingException (uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationProviderMappingException)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 HttpServletRequest (javax.servlet.http.HttpServletRequest)2 HttpServletResponse (javax.servlet.http.HttpServletResponse)2 HttpSession (javax.servlet.http.HttpSession)2 Test (org.junit.Test)2 NoUserLoggedInException (uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserLoggedInException)2 ApiOperation (io.swagger.annotations.ApiOperation)1 GET (javax.ws.rs.GET)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1 SegueErrorResponse (uk.ac.cam.cl.dtg.isaac.dto.SegueErrorResponse)1 RegisteredUserDTO (uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO)1 IOAuth1Authenticator (uk.ac.cam.cl.dtg.segue.auth.IOAuth1Authenticator)1 IOAuth2Authenticator (uk.ac.cam.cl.dtg.segue.auth.IOAuth2Authenticator)1 AccountAlreadyLinkedException (uk.ac.cam.cl.dtg.segue.auth.exceptions.AccountAlreadyLinkedException)1 AuthenticationCodeException (uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticationCodeException)1 AuthenticatorSecurityException (uk.ac.cam.cl.dtg.segue.auth.exceptions.AuthenticatorSecurityException)1