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;
}
}
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();
}
}
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);
}
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);
}
Aggregations