@Before public void setup() { MockitoAnnotations.initMocks(this); initMocks(MOCK_USER_INFO_URI, MOCK_USER_INFO_RESPONSE); defaultOAuth2UserInfoProvider.setClient(client); given(oAuth2ServiceProperties.getUserInfoUri()).willReturn(MOCK_USER_INFO_URI); given(oAuth2ServiceProperties.getAccessTokenName()).willReturn("access_token"); }
/** Check properties are set */ @Override public void afterPropertiesSet() { super.afterPropertiesSet(); Assert.notNull(oAuth2ServiceProperties); Assert.isTrue( oAuth2ServiceProperties.getRedirectUri().endsWith(super.getFilterProcessesUrl()), "The filter must be configured to be listening on the redirect_uri in OAuth2ServiceProperties"); }
@Test public void shouldIncludeOptionalInfoParams() { Map<String, String> additionalInfoParams = Collections.singletonMap("extra_param", "param_value"); given(oAuth2ServiceProperties.getAdditionalInfoParams()).willReturn(additionalInfoParams); Map<String, Object> userInfo = defaultOAuth2UserInfoProvider.getUserInfoFromProvider(token); assertThat(userInfo, notNullValue()); verify(webTarget).queryParam("extra_param", "param_value"); }
/** * Check the state parameter to ensure it is the same as was originally sent. Subclasses can * override this behaviour if they so choose, but it is not recommended. * * @param session The http session, which will contain the original scope as an attribute. * @param parameters The parameters received from the OAuth 2 Provider, which should contain the * same state as originally sent to it and stored in the http session. * @throws AuthenticationException If the state differs from the original. */ protected void checkStateParameter(HttpSession session, Map<String, String[]> parameters) throws AuthenticationException { String originalState = (String) session.getAttribute(oAuth2ServiceProperties.getStateParamName()); String receivedStates[] = parameters.get(oAuth2ServiceProperties.getStateParamName()); // There should only be one entry in the array, if there are more they will be ignored. if (receivedStates == null || receivedStates.length == 0 || !receivedStates[0].equals(originalState)) { String errorMsg = String.format( "Received states %s was not equal to original state %s", receivedStates, originalState); LOG.error(errorMsg); throw new AuthenticationServiceException(errorMsg); } }
/** * Performs actual authentication. * * <p>The implementation should do one of the following: * * <ol> * <li>Return a populated authentication token for the authenticated user, indicating successful * authentication * <li>Return null, indicating that the authentication process is still in progress. Before * returning, the implementation should perform any additional work required to complete the * process. * <li>Throw an <tt>AuthenticationException</tt> if the authentication process fails * </ol> * * @param request from which to extract parameters and perform the authentication * @param response the response, which may be needed if the implementation has to do a redirect as * part of a multi-stage authentication process (such as OpenID). * @return the authenticated user token, or null if authentication is incomplete. * @throws org.springframework.security.core.AuthenticationException if authentication fails. */ @Override public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { String code = null; if (LOG.isDebugEnabled()) { String url = request.getRequestURI(); String queryString = request.getQueryString(); LOG.debug("attemptAuthentication on url {}?{}", url, queryString); } // request parameters final Map<String, String[]> parameters = request.getParameterMap(); LOG.debug("Got Parameters: {}", parameters); // Check to see if there was an error response from the OAuth Provider checkForErrors(parameters); // Check state parameter to avoid cross-site-scripting attacks checkStateParameter(request.getSession(), parameters); final String codeValues[] = parameters.get(oAuth2ServiceProperties.getCodeParamName()); if (codeValues != null && codeValues.length > 0) { code = codeValues[0]; LOG.debug("Got code {}", code); } OAuth2AuthenticationToken authRequest = new OAuth2AuthenticationToken(code); // Allow subclasses to set the "details" property setDetails(request, authRequest); authRequest.setRedirectUri(oAuth2ServiceProperties.getAbsoluteRedirectUri(request)); return this.getAuthenticationManager().authenticate(authRequest); }