use of org.springframework.security.oauth2.common.exceptions.RedirectMismatchException in project spring-security-oauth by spring-projects.
the class AuthorizationEndpoint method authorize.
@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters, SessionStatus sessionStatus, Principal principal) {
// Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
// query off of the authorization request instead of referring back to the parameters map. The contents of the
// parameters map will be stored without change in the AuthorizationRequest object once it is created.
AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
Set<String> responseTypes = authorizationRequest.getResponseTypes();
if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
}
if (authorizationRequest.getClientId() == null) {
throw new InvalidClientException("A client id must be provided");
}
try {
if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
throw new InsufficientAuthenticationException("User must be authenticated with Spring Security before authorization can be completed.");
}
ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId());
// The resolved redirect URI is either the redirect_uri from the parameters or the one from
// clientDetails. Either way we need to store it on the AuthorizationRequest.
String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
String resolvedRedirect = redirectResolver.resolveRedirect(redirectUriParameter, client);
if (!StringUtils.hasText(resolvedRedirect)) {
throw new RedirectMismatchException("A redirectUri must be either supplied or preconfigured in the ClientDetails");
}
authorizationRequest.setRedirectUri(resolvedRedirect);
// We intentionally only validate the parameters requested by the client (ignoring any data that may have
// been added to the request by the manager).
oauth2RequestValidator.validateScope(authorizationRequest, client);
// Some systems may allow for approval decisions to be remembered or approved by default. Check for
// such logic here, and set the approved flag on the authorization request accordingly.
authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest, (Authentication) principal);
// TODO: is this call necessary?
boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
authorizationRequest.setApproved(approved);
// Validation is all done, so we can check for auto approval...
if (authorizationRequest.isApproved()) {
if (responseTypes.contains("token")) {
return getImplicitGrantResponse(authorizationRequest);
}
if (responseTypes.contains("code")) {
return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal));
}
}
// Place auth request into the model so that it is stored in the session
// for approveOrDeny to use. That way we make sure that auth request comes from the session,
// so any auth request parameters passed to approveOrDeny will be ignored and retrieved from the session.
model.put("authorizationRequest", authorizationRequest);
return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
} catch (RuntimeException e) {
sessionStatus.setComplete();
throw e;
}
}
use of org.springframework.security.oauth2.common.exceptions.RedirectMismatchException in project spring-security-oauth by spring-projects.
the class AuthorizationCodeTokenGranter method getOAuth2Authentication.
@Override
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
Map<String, String> parameters = tokenRequest.getRequestParameters();
String authorizationCode = parameters.get("code");
String redirectUri = parameters.get(OAuth2Utils.REDIRECT_URI);
if (authorizationCode == null) {
throw new InvalidRequestException("An authorization code must be supplied.");
}
OAuth2Authentication storedAuth = authorizationCodeServices.consumeAuthorizationCode(authorizationCode);
if (storedAuth == null) {
throw new InvalidGrantException("Invalid authorization code: " + authorizationCode);
}
OAuth2Request pendingOAuth2Request = storedAuth.getOAuth2Request();
// https://jira.springsource.org/browse/SECOAUTH-333
// This might be null, if the authorization was done without the redirect_uri parameter
String redirectUriApprovalParameter = pendingOAuth2Request.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
if ((redirectUri != null || redirectUriApprovalParameter != null) && !pendingOAuth2Request.getRedirectUri().equals(redirectUri)) {
throw new RedirectMismatchException("Redirect URI mismatch.");
}
String pendingClientId = pendingOAuth2Request.getClientId();
String clientId = tokenRequest.getClientId();
if (clientId != null && !clientId.equals(pendingClientId)) {
// just a sanity check.
throw new InvalidClientException("Client ID mismatch");
}
// Secret is not required in the authorization request, so it won't be available
// in the pendingAuthorizationRequest. We do want to check that a secret is provided
// in the token request, but that happens elsewhere.
Map<String, String> combinedParameters = new HashMap<String, String>(pendingOAuth2Request.getRequestParameters());
// Combine the parameters adding the new ones last so they override if there are any clashes
combinedParameters.putAll(parameters);
// Make a new stored request with the combined parameters
OAuth2Request finalStoredOAuth2Request = pendingOAuth2Request.createOAuth2Request(combinedParameters);
Authentication userAuth = storedAuth.getUserAuthentication();
return new OAuth2Authentication(finalStoredOAuth2Request, userAuth);
}
use of org.springframework.security.oauth2.common.exceptions.RedirectMismatchException in project ORCID-Source by ORCID.
the class OauthLoginController method authenticateAndAuthorize.
@RequestMapping(value = { "/oauth/custom/signin.json", "/oauth/custom/login.json" }, method = RequestMethod.POST)
@ResponseBody
public OauthAuthorizeForm authenticateAndAuthorize(HttpServletRequest request, HttpServletResponse response, @RequestBody OauthAuthorizeForm form) {
// Clean form errors
form.setErrors(new ArrayList<String>());
RequestInfoForm requestInfoForm = (RequestInfoForm) request.getSession().getAttribute(REQUEST_INFO_FORM);
boolean willBeRedirected = false;
if (form.getApproved()) {
// Validate name and password
validateUserNameAndPassword(form);
if (form.getErrors().isEmpty()) {
try {
// Authenticate user
copy2FAFields(form, request);
Authentication auth = authenticateUser(request, form.getUserName().getValue(), form.getPassword().getValue());
profileEntityManager.updateLastLoginDetails(auth.getName(), OrcidRequestUtil.getIpAddress(request));
// Create authorization params
SimpleSessionStatus status = new SimpleSessionStatus();
Map<String, Object> model = new HashMap<String, Object>();
Map<String, String> params = new HashMap<String, String>();
Map<String, String> approvalParams = new HashMap<String, String>();
fillOauthParams(requestInfoForm, params, approvalParams, form.getPersistentTokenEnabled(), form.isEmailAccessAllowed());
// Authorize
try {
authorizationEndpoint.authorize(model, params, status, auth);
} catch (RedirectMismatchException rUriError) {
String redirectUri = this.getBaseUri() + REDIRECT_URI_ERROR;
// Set the client id
redirectUri = redirectUri.replace("{0}", requestInfoForm.getClientId());
// Set the response type if needed
if (!PojoUtil.isEmpty(requestInfoForm.getResponseType()))
redirectUri += "&response_type=" + requestInfoForm.getResponseType();
// Set the redirect uri
if (!PojoUtil.isEmpty(requestInfoForm.getRedirectUrl()))
redirectUri += "&redirect_uri=" + requestInfoForm.getRedirectUrl();
// Set the scope param
if (!PojoUtil.isEmpty(requestInfoForm.getScopesAsString()))
redirectUri += "&scope=" + requestInfoForm.getScopesAsString();
// Copy the state param if present
if (!PojoUtil.isEmpty(requestInfoForm.getStateParam()))
redirectUri += "&state=" + requestInfoForm.getStateParam();
form.setRedirectUrl(redirectUri);
LOGGER.info("OauthLoginController being sent to client browser: " + form.getRedirectUrl());
return form;
}
// Approve
RedirectView view = (RedirectView) authorizationEndpoint.approveOrDeny(approvalParams, model, status, auth);
form.setRedirectUrl(view.getUrl());
willBeRedirected = true;
} catch (AuthenticationException ae) {
if (ae.getCause() instanceof DisabledException) {
// Handle this message in angular to allow AJAX action
form.getErrors().add("orcid.frontend.security.orcid_deactivated");
} else if (ae.getCause() instanceof UnclaimedProfileExistsException) {
String email = PojoUtil.isEmpty(form.getUserName()) ? null : form.getUserName().getValue();
String resendEmailUrl = createResendClaimUrl(email, request);
String errorMessage = getMessage("orcid.frontend.security.unclaimed_exists_1");
errorMessage += "<a href=\"" + resendEmailUrl + "\">";
errorMessage += getMessage("orcid.frontend.security.unclaimed_exists_2");
errorMessage += "</a>" + getMessage("orcid.frontend.security.unclaimed_exists_3");
form.getErrors().add(errorMessage);
} else if (ae instanceof VerificationCodeFor2FARequiredException) {
form.setVerificationCodeRequired(true);
} else if (ae instanceof Bad2FAVerificationCodeException) {
form.getErrors().add(getMessage("orcid.frontend.security.2fa.bad_verification_code"));
} else if (ae instanceof Bad2FARecoveryCodeException) {
form.getErrors().add(getMessage("orcid.frontend.security.2fa.bad_recovery_code"));
} else {
form.getErrors().add(getMessage("orcid.frontend.security.bad_credentials"));
}
}
}
} else {
form.setRedirectUrl(buildDenyRedirectUri(requestInfoForm.getRedirectUrl(), requestInfoForm.getStateParam()));
willBeRedirected = true;
}
// not be redirected yet
if (willBeRedirected) {
if (new HttpSessionRequestCache().getRequest(request, response) != null)
new HttpSessionRequestCache().removeRequest(request, response);
LOGGER.info("OauthConfirmAccessController form.getRedirectUri being sent to client browser: " + requestInfoForm.getRedirectUrl());
}
return form;
}
use of org.springframework.security.oauth2.common.exceptions.RedirectMismatchException in project spring-security-oauth by spring-projects.
the class AuthorizationCodeProviderTests method testWrongRedirectUri.
@Test
@OAuth2ContextConfiguration(resource = MyLessTrustedClient.class, initialize = false)
public void testWrongRedirectUri() throws Exception {
approveAccessTokenGrant("http://anywhere", true);
AccessTokenRequest request = context.getAccessTokenRequest();
// The redirect is stored in the preserved state...
context.getOAuth2ClientContext().setPreservedState(request.getStateKey(), "http://nowhere");
// Finally everything is in place for the grant to happen...
try {
assertNotNull(context.getAccessToken());
fail("Expected RedirectMismatchException");
} catch (RedirectMismatchException e) {
// expected
}
assertEquals(HttpStatus.BAD_REQUEST, tokenEndpointResponse.getStatusCode());
}
use of org.springframework.security.oauth2.common.exceptions.RedirectMismatchException in project spring-security-oauth by spring-projects.
the class AuthorizationEndpoint method handleException.
private ModelAndView handleException(Exception e, ServletWebRequest webRequest) throws Exception {
ResponseEntity<OAuth2Exception> translate = getExceptionTranslator().translate(e);
webRequest.getResponse().setStatus(translate.getStatusCode().value());
if (e instanceof ClientAuthenticationException || e instanceof RedirectMismatchException) {
return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody()));
}
AuthorizationRequest authorizationRequest = null;
try {
authorizationRequest = getAuthorizationRequestForError(webRequest);
String requestedRedirectParam = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
String requestedRedirect = redirectResolver.resolveRedirect(requestedRedirectParam, getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId()));
authorizationRequest.setRedirectUri(requestedRedirect);
String redirect = getUnsuccessfulRedirect(authorizationRequest, translate.getBody(), authorizationRequest.getResponseTypes().contains("token"));
return new ModelAndView(new RedirectView(redirect, false, true, false));
} catch (OAuth2Exception ex) {
// response.
return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody()));
}
}
Aggregations