private String getRedirectUri(ClientDetails client, AuthorizationRequest clientAuth) { String result = null; if (clientAuth.getRedirectUri() != null) { result = clientAuth.getRedirectUri(); } if (client.getRegisteredRedirectUri() != null && !client.getRegisteredRedirectUri().isEmpty() && result == null) { result = client.getRegisteredRedirectUri().iterator().next(); } if (result != null) { if (result.contains("?")) { result = result.substring(0, result.indexOf("?")); } if (result.contains("#")) { result = result.substring(0, result.indexOf("#")); } } return result; }
private Set<String> getClientWhitelist(HttpServletRequest request) { String clientId = request.getParameter(CLIENT_ID); Set<String> redirectUris = null; if (StringUtils.hasText(clientId)) { try { ClientDetails client = clientDetailsService.loadClientByClientId(clientId, IdentityZoneHolder.get().getId()); redirectUris = client.getRegisteredRedirectUri(); } catch (NoSuchClientException x) { logger.debug(String.format("Unable to find client with ID:%s for logout redirect", clientId)); } } return redirectUris; }
@Override public String resolveRedirect(String requestedRedirect, ClientDetails client) throws OAuth2Exception { Set<String> registeredRedirectUris = ofNullable(client.getRegisteredRedirectUri()).orElse(emptySet()); if (registeredRedirectUris.isEmpty()) { throw new RedirectMismatchException("Client registration is missing redirect_uri"); } List<String> invalidUrls = registeredRedirectUris.stream() .filter(url -> !UaaUrlUtils.isValidRegisteredRedirectUrl(url)) .collect(Collectors.toList()); if (!invalidUrls.isEmpty()) { throw new RedirectMismatchException("Client registration contains invalid redirect_uri: " + invalidUrls); } return super.resolveRedirect(requestedRedirect, client); } }
private String getRedirect(String clientId, String redirectUri) throws IOException { if (clientId != null) { try { ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId, IdentityZoneHolder.get().getId()); Set<String> registeredRedirectUris = clientDetails.getRegisteredRedirectUri() == null ? Collections.emptySet() : clientDetails.getRegisteredRedirectUri(); String signupRedirectUrl = (String) clientDetails.getAdditionalInformation().get(SIGNUP_REDIRECT_URL); String matchingRedirectUri = findMatchingRedirectUri(registeredRedirectUris, redirectUri, Optional.ofNullable(signupRedirectUrl).orElse("home")); if (matchingRedirectUri != null) { return matchingRedirectUri; } } catch (NoSuchClientException nsce) { logger.debug(String.format("Unable to find client with ID:%s for account activation redirect", clientId), nsce); } } return getDefaultRedirect(); }
public String resolveRedirect(String requestedRedirect, ClientDetails client) throws OAuth2Exception { Set<String> authorizedGrantTypes = client.getAuthorizedGrantTypes(); if (authorizedGrantTypes.isEmpty()) { throw new InvalidGrantException("A client must have at least one authorized grant type."); } if (!containsRedirectGrantType(authorizedGrantTypes)) { throw new InvalidGrantException( "A redirect_uri can only be used by implicit or authorization_code grant types."); } Set<String> registeredRedirectUris = client.getRegisteredRedirectUri(); if (registeredRedirectUris == null || registeredRedirectUris.isEmpty()) { throw new InvalidRequestException("At least one redirect_uri must be registered with the client."); } return obtainMatchingRedirect(registeredRedirectUris, requestedRedirect); }
public void validateClientRedirectUri(ClientDetails client) { Set<String> uris = client.getRegisteredRedirectUri(); for(String grant_type: Arrays.asList(GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_IMPLICIT)) { if(client.getAuthorizedGrantTypes().contains(grant_type)) { if (isMissingRedirectUris(uris)) { throw new InvalidClientDetailsException(grant_type + " grant type requires at least one redirect URL."); } for (String uri : uris) { if (!UaaUrlUtils.isValidRegisteredRedirectUrl(uri)) { throw new InvalidClientDetailsException( String.format("One of the redirect_uri is invalid: %s", uri)); } } } } }
@Test public void testSimpleAddClientWithSignupSuccessRedirectUrl() throws Exception { Map<String, Object> map = new HashMap<>(); map.put("id", "foo"); map.put("secret", "bar"); map.put("scope", "openid"); map.put("authorized-grant-types", GRANT_TYPE_AUTHORIZATION_CODE); map.put("authorities", "uaa.none"); map.put("signup_redirect_url", "callback_url"); ClientDetails clientDetails = doSimpleTest(map); assertTrue(clientDetails.getRegisteredRedirectUri().contains("callback_url")); }
@Test public void testSimpleAddClientWithChangeEmailRedirectUrl() throws Exception { Map<String, Object> map = new HashMap<>(); map.put("id", "foo"); map.put("secret", "bar"); map.put("scope", "openid"); map.put("authorized-grant-types", GRANT_TYPE_AUTHORIZATION_CODE); map.put("authorities", "uaa.none"); map.put("change_email_redirect_url", "change_email_callback_url"); ClientDetails created = doSimpleTest(map); assertTrue(created.getRegisteredRedirectUri().contains("change_email_callback_url")); }
@Test void clientWithValidRedirectUri_shouldResolve() { when(mockClientDetails.getRegisteredRedirectUri()).thenReturn(Collections.singleton("http://uaa.com")); String resolvedRedirect = resolver.resolveRedirect("http://uaa.com", mockClientDetails); assertThat(resolvedRedirect, equalTo("http://uaa.com")); }
@Test public void testAdditionalInformation() throws Exception { List<String> idps = Arrays.asList("idp1", "idp1"); Map<String, Object> map = new HashMap<>(); map.put("id", "foo"); map.put("secret", "bar"); map.put("scope", "openid"); map.put("authorized-grant-types", GRANT_TYPE_AUTHORIZATION_CODE); map.put("authorities", "uaa.none"); map.put("signup_redirect_url", "callback_url"); map.put("change_email_redirect_url", "change_email_url"); map.put(ClientConstants.ALLOWED_PROVIDERS, idps); ClientDetails created = doSimpleTest(map); assertEquals(idps, created.getAdditionalInformation().get(ClientConstants.ALLOWED_PROVIDERS)); assertTrue(created.getRegisteredRedirectUri().contains("callback_url")); assertTrue(created.getRegisteredRedirectUri().contains("change_email_url")); }
@Test public void completeActivation_usesAntPathMatching() throws Exception { setUpForSuccess("http://redirect.uri/"); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.createUser(any(ScimUser.class), anyString(), eq(zoneId))).thenReturn(user); when(codeStore.retrieveCode("the_secret_code", zoneId)).thenReturn(code); when(scimUserProvisioning.retrieve(anyString(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); ClientDetails client = mock(ClientDetails.class); when(clientDetailsService.loadClientByClientId(anyString(), anyString())).thenReturn(client); when(client.getRegisteredRedirectUri()).thenReturn(Collections.singleton("http://redirect.uri/*")); AccountCreationService.AccountCreationResponse accountCreation = emailAccountCreationService.completeActivation("the_secret_code"); assertThat(accountCreation.getRedirectLocation(), equalTo("http://redirect.uri/")); }
@Test void clientMissingRedirectUri() { when(mockClientDetails.getRegisteredRedirectUri()).thenReturn(new HashSet<>()); RedirectMismatchException exception = assertThrows(RedirectMismatchException.class, () -> resolver.resolveRedirect("http://somewhere.com", mockClientDetails)); assertThat(exception.getMessage(), containsString("Client registration is missing redirect_uri")); }
public ClientDetails testSimpleAddClient(String clientId) throws Exception { Map<String, Object> map = createClientMap(clientId); ClientDetails created = doSimpleTest(map); assertSet((String) map.get("redirect-uri"), null, created.getRegisteredRedirectUri(), String.class); return created; }
@Test void clientWithInvalidRedirectUri() { when(mockClientDetails.getRegisteredRedirectUri()).thenReturn(Collections.singleton("*, */*")); RedirectMismatchException exception = assertThrows(RedirectMismatchException.class, () -> resolver.resolveRedirect("http://somewhere.com", mockClientDetails)); assertThat(exception.getMessage(), containsString("Client registration contains invalid redirect_uri")); assertThat(exception.getMessage(), containsString("*, */*")); }
@Test public void testCompleteActivation() throws Exception { setUpForSuccess(""); String zoneId = IdentityZoneHolder.get().getId(); when(scimUserProvisioning.createUser(any(ScimUser.class), anyString(), eq(zoneId))).thenReturn(user); when(codeStore.retrieveCode("the_secret_code", zoneId)).thenReturn(code); when(scimUserProvisioning.retrieve(anyString(), eq(zoneId))).thenReturn(user); when(scimUserProvisioning.verifyUser(anyString(), anyInt(), eq(zoneId))).thenReturn(user); ClientDetails client = mock(ClientDetails.class); when(clientDetailsService.loadClientByClientId(anyString(), anyString())).thenReturn(client); when(client.getRegisteredRedirectUri()).thenReturn(Collections.emptySet()); Map<String, Object> map = new HashMap<>(); map.put(EmailAccountCreationService.SIGNUP_REDIRECT_URL, "http://fallback.url/redirect"); when(client.getAdditionalInformation()).thenReturn(map); AccountCreationService.AccountCreationResponse accountCreation = emailAccountCreationService.completeActivation("the_secret_code"); assertEquals("user@example.com", accountCreation.getUsername()); assertEquals("newly-created-user-id", accountCreation.getUserId()); assertNotNull(accountCreation.getUserId()); }
private Object[] getFieldsForUpdate(ClientDetails clientDetails) { String json = null; try { json = mapper.write(clientDetails.getAdditionalInformation()); } catch (Exception e) { logger.warn("Could not serialize additional information: " + clientDetails, e); } return new Object[] { clientDetails.getResourceIds() != null ? StringUtils.collectionToCommaDelimitedString(clientDetails .getResourceIds()) : null, clientDetails.getScope() != null ? StringUtils.collectionToCommaDelimitedString(clientDetails .getScope()) : null, clientDetails.getAuthorizedGrantTypes() != null ? StringUtils .collectionToCommaDelimitedString(clientDetails.getAuthorizedGrantTypes()) : null, clientDetails.getRegisteredRedirectUri() != null ? StringUtils .collectionToCommaDelimitedString(clientDetails.getRegisteredRedirectUri()) : null, clientDetails.getAuthorities() != null ? StringUtils.collectionToCommaDelimitedString(clientDetails .getAuthorities()) : null, clientDetails.getAccessTokenValiditySeconds(), clientDetails.getRefreshTokenValiditySeconds(), json, getAutoApproveScopes(clientDetails), clientDetails.getClientId() }; }
@Test public void testChangePasswordDuringBootstrap() throws Exception { Map<String, Object> map = createClientMap("foo"); ClientDetails created = doSimpleTest(map); assertSet((String) map.get("redirect-uri"), null, created.getRegisteredRedirectUri(), String.class); ClientDetails details = clientRegistrationService.loadClientByClientId("foo"); assertTrue("Password should match bar:", bootstrap.getPasswordEncoder().matches("bar", details.getClientSecret())); map.put("secret", "bar1"); created = doSimpleTest(map); assertSet((String) map.get("redirect-uri"), null, created.getRegisteredRedirectUri(), String.class); details = clientRegistrationService.loadClientByClientId("foo"); assertTrue("Password should match bar1:", bootstrap.getPasswordEncoder().matches("bar1", details.getClientSecret())); assertFalse("Password should not match bar:", bootstrap.getPasswordEncoder().matches("bar", details.getClientSecret())); }
public BaseClientDetails(ClientDetails prototype) { this(); setAccessTokenValiditySeconds(prototype.getAccessTokenValiditySeconds()); setRefreshTokenValiditySeconds(prototype .getRefreshTokenValiditySeconds()); setAuthorities(prototype.getAuthorities()); setAuthorizedGrantTypes(prototype.getAuthorizedGrantTypes()); setClientId(prototype.getClientId()); setClientSecret(prototype.getClientSecret()); setRegisteredRedirectUri(prototype.getRegisteredRedirectUri()); setScope(prototype.getScope()); setResourceIds(prototype.getResourceIds()); }
@Test public void testPasswordHashDidNotChangeDuringBootstrap() throws Exception { Map<String, Object> map = createClientMap("foo"); ClientDetails created = doSimpleTest(map); assertSet((String) map.get("redirect-uri"), null, created.getRegisteredRedirectUri(), String.class); ClientDetails details = clientRegistrationService.loadClientByClientId("foo"); assertTrue("Password should match bar:", bootstrap.getPasswordEncoder().matches("bar", details.getClientSecret())); String hash = details.getClientSecret(); created = doSimpleTest(map); assertSet((String) map.get("redirect-uri"), null, created.getRegisteredRedirectUri(), String.class); details = clientRegistrationService.loadClientByClientId("foo"); assertTrue("Password should match bar:", bootstrap.getPasswordEncoder().matches("bar", details.getClientSecret())); assertEquals("Password hash must not change on an update:", hash, details.getClientSecret()); }
@Test public void testLoadingClientIdWithNoDetails() { int rowsInserted = jdbcTemplate.update(INSERT_SQL, "clientIdWithNoDetails", null, null, null, null, null, null, null, null, null, IdentityZoneHolder.get().getId(), new Timestamp(System.currentTimeMillis()), dbRequestedUserGroups ); assertEquals(1, rowsInserted); ClientDetails clientDetails = service .loadClientByClientId("clientIdWithNoDetails"); assertEquals("clientIdWithNoDetails", clientDetails.getClientId()); assertFalse(clientDetails.isSecretRequired()); assertNull(clientDetails.getClientSecret()); assertFalse(clientDetails.isScoped()); assertEquals(0, clientDetails.getScope().size()); assertEquals(2, clientDetails.getAuthorizedGrantTypes().size()); assertNull(clientDetails.getRegisteredRedirectUri()); assertEquals(0, clientDetails.getAuthorities().size()); assertEquals(null, clientDetails.getAccessTokenValiditySeconds()); assertEquals(null, clientDetails.getAccessTokenValiditySeconds()); }