Ejemplo n.º 1
0
  private void checkPasswordChangeIsAllowed(String userId, String oldPassword) {
    if (securityContextAccessor.isClient()) {
      // Trusted client (not acting on behalf of user)
      return;
    }

    // Call is by or on behalf of end user
    String currentUser = securityContextAccessor.getUserId();

    if (securityContextAccessor.isAdmin()) {

      // even an admin needs to provide the old value to change his
      // password
      if (userId.equals(currentUser) && !StringUtils.hasText(oldPassword)) {
        throw new InvalidPasswordException("Previous password is required even for admin");
      }

    } else {

      if (!userId.equals(currentUser)) {
        logger.warn(
            "User with id " + currentUser + " attempting to change password for user " + userId);
        // TODO: This should be audited when we have non-authentication
        // events in the log
        throw new InvalidPasswordException("Not permitted to change another user's password");
      }

      // User is changing their own password, old password is required
      if (!StringUtils.hasText(oldPassword)) {
        throw new InvalidPasswordException("Previous password is required");
      }
    }
  }
  /**
   * Create an authorization request applying various UAA rules to the authorizationParameters and
   * the registered client details.
   *
   * <ul>
   *   <li>For client_credentials grants, the default scopes are the client's granted authorities
   *   <li>For other grant types the default scopes are the registered scopes in the client details
   *   <li>Only scopes in those lists are valid, otherwise there is an exception
   *   <li>If the scopes contain separators then resource ids are extracted as the scope value up to
   *       the last index of the separator
   *   <li>Some scopes can be hard-wired to resource ids (like the open id connect values), in which
   *       case the separator is ignored
   * </ul>
   *
   * @see
   *     org.springframework.security.oauth2.provider.AuthorizationRequestFactory#createAuthorizationRequest(java.util.Map,
   *     java.lang.String, java.lang.String, java.util.Set)
   */
  @Override
  public AuthorizationRequest createAuthorizationRequest(
      Map<String, String> authorizationParameters) {

    String clientId = authorizationParameters.get("client_id");
    BaseClientDetails clientDetails =
        new BaseClientDetails(clientDetailsService.loadClientByClientId(clientId));

    Set<String> scopes = OAuth2Utils.parseParameterList(authorizationParameters.get("scope"));
    String grantType = authorizationParameters.get("grant_type");
    if ((scopes == null || scopes.isEmpty())) {
      if ("client_credentials".equals(grantType)) {
        // The client authorities should be a list of scopes
        scopes = AuthorityUtils.authorityListToSet(clientDetails.getAuthorities());
      } else {
        // The default for a user token is the scopes registered with
        // the client
        scopes = clientDetails.getScope();
      }
    }

    Set<String> scopesFromExternalAuthorities = null;
    if (!"client_credentials".equals(grantType) && securityContextAccessor.isUser()) {
      scopes = checkUserScopes(scopes, securityContextAccessor.getAuthorities(), clientDetails);

      // TODO: will the grantType ever contain client_credentials or
      // authorization_code
      // External Authorities are things like LDAP groups that will be
      // mapped to Oauth scopes
      // Add those scopes to the request. These scopes will not be
      // validated against the scopes
      // registered to a client.
      // These scopes also do not need approval. The fact that they are
      // already in an external
      // group communicates user approval. Denying approval does not mean
      // much
      scopesFromExternalAuthorities =
          findScopesFromAuthorities(authorizationParameters.get("authorities"));
    }

    Set<String> resourceIds = getResourceIds(clientDetails, scopes);
    clientDetails.setResourceIds(resourceIds);
    DefaultAuthorizationRequest request = new DefaultAuthorizationRequest(authorizationParameters);
    if (!scopes.isEmpty()) {
      request.setScope(scopes);
    }
    if (scopesFromExternalAuthorities != null) {
      Map<String, String> existingAuthorizationParameters = new LinkedHashMap<String, String>();
      existingAuthorizationParameters.putAll(request.getAuthorizationParameters());
      existingAuthorizationParameters.put(
          "external_scopes", OAuth2Utils.formatParameterList(scopesFromExternalAuthorities));
      request.setAuthorizationParameters(existingAuthorizationParameters);
    }

    request.addClientDetails(clientDetails);

    return request;
  }
 @Test
 public void clientCanChangeUserPasswordWithoutCurrentPassword() {
   SecurityContextAccessor sca = mockSecurityContext(joel);
   when(sca.isClient()).thenReturn(true);
   endpoints.setSecurityContextAccessor(sca);
   PasswordChangeRequest change = new PasswordChangeRequest();
   change.setPassword("newpassword");
   endpoints.changePassword(joel.getId(), change);
 }
 @Test
 public void adminCanChangeAnotherUsersPassword() {
   SecurityContextAccessor sca = mockSecurityContext(dale);
   when(sca.isAdmin()).thenReturn(true);
   endpoints.setSecurityContextAccessor(sca);
   PasswordChangeRequest change = new PasswordChangeRequest();
   change.setPassword("newpassword");
   endpoints.changePassword(joel.getId(), change);
 }
 @SuppressWarnings("unchecked")
 @Before
 public void init() {
   endpoints.setScimUserEndpoints(scimUserEndpoints);
   endpoints.setEnabled(true);
   when(securityContextAccessor.getAuthorities()).thenReturn(authorities);
   when(securityContextAccessor.getAuthenticationInfo()).thenReturn("mock object");
   when(provisioning.retrieveActive(anyString()))
       .thenReturn(
           Collections.singletonList(MultitenancyFixture.identityProvider("test-origin", "uaa")));
   endpoints.setSecurityContextAccessor(securityContextAccessor);
 }
Ejemplo n.º 6
0
  private void checkPasswordChangeIsAllowed(ClientDetails clientDetails, String oldSecret) {

    if (!securityContextAccessor.isClient()) {
      // Trusted client (not acting on behalf of user)
      throw new IllegalStateException("Only a client can change client secret");
    }

    String clientId = clientDetails.getClientId();

    // Call is by client
    String currentClientId = securityContextAccessor.getClientId();

    if (securityContextAccessor.isAdmin()) {

      // even an admin needs to provide the old value to change password
      if (clientId.equals(currentClientId) && !StringUtils.hasText(oldSecret)) {
        throw new IllegalStateException("Previous secret is required even for admin");
      }

    } else {

      if (!clientId.equals(currentClientId)) {
        logger.warn(
            "Client with id "
                + currentClientId
                + " attempting to change password for client "
                + clientId);
        // TODO: This should be audited when we have non-authentication events in the log
        throw new IllegalStateException(
            "Bad request. Not permitted to change another client's secret");
      }

      // Client is changing their own secret, old password is required
      if (!StringUtils.hasText(oldSecret)) {
        throw new IllegalStateException("Previous secret is required");
      }
    }
  }
Ejemplo n.º 7
0
  @RequestMapping(value = "/ids/Users")
  @ResponseBody
  public SearchResults<?> findUsers(
      @RequestParam(required = true, defaultValue = "") String filter,
      @RequestParam(required = false, defaultValue = "ascending") String sortOrder,
      @RequestParam(required = false, defaultValue = "1") int startIndex,
      @RequestParam(required = false, defaultValue = "100") int count,
      @RequestParam(required = false, defaultValue = "false") boolean includeInactive) {
    if (!enabled) {
      logger.warn(
          "Request from user "
              + securityContextAccessor.getAuthenticationInfo()
              + " received at disabled Id translation endpoint with filter:"
              + filter);
      throw new ScimException("Illegal operation.", HttpStatus.BAD_REQUEST);
    }

    filter = filter.trim();
    checkFilter(filter);

    List<IdentityProvider> activeIdentityProviders =
        provisioning.retrieveActive(IdentityZoneHolder.get().getId());

    if (!includeInactive) {
      if (activeIdentityProviders.isEmpty()) {
        return new SearchResults<>(
            Arrays.asList(ScimCore.SCHEMAS), new ArrayList<>(), startIndex, count, 0);
      }
      String originFilter =
          activeIdentityProviders
              .stream()
              .map(
                  identityProvider ->
                      "".concat("origin eq \"" + identityProvider.getOriginKey() + "\""))
              .collect(Collectors.joining(" OR "));
      filter += " AND (" + originFilter + " )";
    }

    return scimUserEndpoints.findUsers(
        "id,userName,origin", filter, "userName", sortOrder, startIndex, count);
  }
Ejemplo n.º 8
0
 private SecurityContextAccessor mockSecurityContextAccessor(String userName) {
   SecurityContextAccessor sca = mock(SecurityContextAccessor.class);
   when(sca.getUserName()).thenReturn(userName);
   when(sca.isUser()).thenReturn(true);
   return sca;
 }
 private SecurityContextAccessor mockSecurityContext(ScimUser user) {
   SecurityContextAccessor sca = mock(SecurityContextAccessor.class);
   String id = user.getId();
   when(sca.getUserId()).thenReturn(id);
   return sca;
 }