/**
  * Endpoint for executing reset credentials flow. If code is null, a client session is created
  * with the account service as the client. Successful reset sends you to the account page. Note,
  * account service must be enabled.
  *
  * @param code
  * @param execution
  * @return
  */
 @Path(RESET_CREDENTIALS_PATH)
 @GET
 public Response resetCredentialsGET(
     @QueryParam("code") String code, @QueryParam("execution") String execution) {
   // we allow applications to link to reset credentials without going through OAuth or SAML
   // handshakes
   //
   if (code == null) {
     if (!realm.isResetPasswordAllowed()) {
       event.event(EventType.RESET_PASSWORD);
       event.error(Errors.NOT_ALLOWED);
       return ErrorPage.error(session, Messages.RESET_CREDENTIAL_NOT_ALLOWED);
     }
     // set up the account service as the endpoint to call.
     ClientModel client = realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID);
     ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
     clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
     clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
     // clientSession.setNote(AuthenticationManager.END_AFTER_REQUIRED_ACTIONS, "true");
     clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
     String redirectUri =
         Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
     clientSession.setRedirectUri(redirectUri);
     clientSession.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
     clientSession.setNote(ClientSessionCode.ACTION_KEY, KeycloakModelUtils.generateCodeSecret());
     clientSession.setNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, OAuth2Constants.CODE);
     clientSession.setNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUri);
     clientSession.setNote(
         OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
     return processResetCredentials(null, clientSession, null);
   }
   return resetCredentials(code, execution);
 }
示例#2
0
  @Path("sessions-logout")
  @GET
  public Response processSessionsLogout(@QueryParam("stateChecker") String stateChecker) {
    if (auth == null) {
      return login("sessions");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(stateChecker);

    UserModel user = auth.getUser();
    List<UserSessionModel> userSessions = session.sessions().getUserSessions(realm, user);
    for (UserSessionModel userSession : userSessions) {
      AuthenticationManager.backchannelLogout(
          session, realm, userSession, uriInfo, clientConnection, headers, true);
    }

    UriBuilder builder =
        Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "sessionsPage");
    String referrer = uriInfo.getQueryParameters().getFirst("referrer");
    if (referrer != null) {
      builder.queryParam("referrer", referrer);
    }
    URI location = builder.build(realm.getName());
    return Response.seeOther(location).build();
  }
示例#3
0
  public String getOauthAction() {
    if (this.actionuri != null) {
      return this.actionuri.getPath();
    }

    return Urls.realmOauthAction(baseURI, realm).toString();
  }
示例#4
0
  private ClientSessionModel createClientSession(
      UserModel user, String redirectUri, String clientId) {

    if (!user.isEnabled()) {
      throw new WebApplicationException(
          ErrorResponse.error("User is disabled", Response.Status.BAD_REQUEST));
    }

    if (redirectUri != null && clientId == null) {
      throw new WebApplicationException(
          ErrorResponse.error("Client id missing", Response.Status.BAD_REQUEST));
    }

    if (clientId == null) {
      clientId = Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
    }

    ClientModel client = realm.getClientByClientId(clientId);
    if (client == null || !client.isEnabled()) {
      throw new WebApplicationException(
          ErrorResponse.error(clientId + " not enabled", Response.Status.BAD_REQUEST));
    }

    String redirect;
    if (redirectUri != null) {
      redirect = RedirectUtils.verifyRedirectUri(uriInfo, redirectUri, realm, client);
      if (redirect == null) {
        throw new WebApplicationException(
            ErrorResponse.error("Invalid redirect uri.", Response.Status.BAD_REQUEST));
      }
    } else {
      redirect = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
    }

    UserSessionModel userSession =
        session
            .sessions()
            .createUserSession(
                realm,
                user,
                user.getUsername(),
                clientConnection.getRemoteAddr(),
                "form",
                false,
                null,
                null);
    // audit.session(userSession);
    ClientSessionModel clientSession = session.sessions().createClientSession(realm, client);
    clientSession.setAuthMethod(OIDCLoginProtocol.LOGIN_PROTOCOL);
    clientSession.setRedirectUri(redirect);
    clientSession.setUserSession(userSession);

    return clientSession;
  }
示例#5
0
  /**
   * Send a update account email to the user
   *
   * <p>An email contains a link the user can click to perform a set of required actions. The
   * redirectUri and clientId parameters are optional. The default for the redirect is the account
   * client.
   *
   * @param id User is
   * @param redirectUri Redirect uri
   * @param clientId Client id
   * @param actions required actions the user needs to complete
   * @return
   */
  @Path("{id}/execute-actions-email")
  @PUT
  @Consumes(MediaType.APPLICATION_JSON)
  public Response executeActionsEmail(
      @PathParam("id") String id,
      @QueryParam(OIDCLoginProtocol.REDIRECT_URI_PARAM) String redirectUri,
      @QueryParam(OIDCLoginProtocol.CLIENT_ID_PARAM) String clientId,
      List<String> actions) {
    auth.requireManage();

    UserModel user = session.users().getUserById(id, realm);
    if (user == null) {
      return ErrorResponse.error("User not found", Response.Status.NOT_FOUND);
    }

    if (user.getEmail() == null) {
      return ErrorResponse.error("User email missing", Response.Status.BAD_REQUEST);
    }

    ClientSessionModel clientSession = createClientSession(user, redirectUri, clientId);
    for (String action : actions) {
      clientSession.addRequiredAction(action);
    }
    ClientSessionCode accessCode = new ClientSessionCode(realm, clientSession);
    accessCode.setAction(ClientSessionModel.Action.EXECUTE_ACTIONS.name());

    try {
      UriBuilder builder = Urls.executeActionsBuilder(uriInfo.getBaseUri());
      builder.queryParam("key", accessCode.getCode());

      String link = builder.build(realm.getName()).toString();
      long expiration = TimeUnit.SECONDS.toMinutes(realm.getAccessCodeLifespanUserAction());

      this.session
          .getProvider(EmailTemplateProvider.class)
          .setRealm(realm)
          .setUser(user)
          .sendExecuteActions(link, expiration);

      // audit.user(user).detail(Details.EMAIL, user.getEmail()).detail(Details.CODE_ID,
      // accessCode.getCodeId()).success();

      adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();

      return Response.ok().build();
    } catch (EmailException e) {
      logger.failedToSendActionsEmail(e);
      return ErrorResponse.error(
          "Failed to send execute actions email", Response.Status.INTERNAL_SERVER_ERROR);
    }
  }
示例#6
0
  private static String verifyRedirectUri(
      UriInfo uriInfo,
      String rootUrl,
      String redirectUri,
      RealmModel realm,
      Set<String> validRedirects) {
    if (redirectUri == null) {
      logger.debug("No Redirect URI parameter specified");
      return null;
    } else if (validRedirects.isEmpty()) {
      logger.debug("No Redirect URIs supplied");
      redirectUri = null;
    } else {
      redirectUri = lowerCaseHostname(redirectUri);

      String r = redirectUri;
      Set<String> resolveValidRedirects = resolveValidRedirects(uriInfo, rootUrl, validRedirects);

      boolean valid = matchesRedirects(resolveValidRedirects, r);

      if (!valid
          && r.startsWith(Constants.INSTALLED_APP_URL)
          && r.indexOf(':', Constants.INSTALLED_APP_URL.length()) >= 0) {
        int i = r.indexOf(':', Constants.INSTALLED_APP_URL.length());

        StringBuilder sb = new StringBuilder();
        sb.append(r.substring(0, i));

        i = r.indexOf('/', i);
        if (i >= 0) {
          sb.append(r.substring(i));
        }

        r = sb.toString();

        valid = matchesRedirects(resolveValidRedirects, r);
      }
      if (valid && redirectUri.startsWith("/")) {
        redirectUri = relativeToAbsoluteURI(uriInfo, rootUrl, redirectUri);
      }
      redirectUri = valid ? redirectUri : null;
    }

    if (Constants.INSTALLED_APP_URN.equals(redirectUri)) {
      return Urls.realmInstalledAppUrnCallback(uriInfo.getBaseUri(), realm.getName()).toString();
    } else {
      return redirectUri;
    }
  }
示例#7
0
  @Path("revoke-grant")
  @POST
  public Response processRevokeGrant(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
      return login("applications");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(formData);

    String clientId = formData.getFirst("clientId");
    if (clientId == null) {
      return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS);
    }
    ClientModel client = realm.getClientById(clientId);
    if (client == null) {
      return account.setError(Messages.CLIENT_NOT_FOUND).createResponse(AccountPages.APPLICATIONS);
    }

    // Revoke grant in UserModel
    UserModel user = auth.getUser();
    user.revokeConsentForClient(client.getId());
    OfflineTokenUtils.revokeOfflineToken(session, realm, user, client);

    // Logout clientSessions for this user and client
    AuthenticationManager.backchannelUserFromClient(session, realm, user, client, uriInfo, headers);

    event
        .event(EventType.REVOKE_GRANT)
        .client(auth.getClient())
        .user(auth.getUser())
        .detail(Details.REVOKED_CLIENT, client.getClientId())
        .success();
    setReferrerOnPage();

    UriBuilder builder =
        Urls.accountBase(uriInfo.getBaseUri()).path(AccountService.class, "applicationsPage");
    String referrer = uriInfo.getQueryParameters().getFirst("referrer");
    if (referrer != null) {
      builder.queryParam("referrer", referrer);
    }
    URI location = builder.build(realm.getName());
    return Response.seeOther(location).build();
  }
示例#8
0
 public String getLogoutUrl() {
   return Urls.accountLogout(baseQueryURI, currentURI, realm).toString();
 }
示例#9
0
 public String getTotpRemoveUrl() {
   return Urls.accountTotpRemove(baseQueryURI, realm, stateChecker).toString();
 }
示例#10
0
 public String getRevokeClientUrl() {
   return Urls.accountRevokeClientPage(baseQueryURI, realm).toString();
 }
示例#11
0
 public String getSessionsLogoutUrl() {
   return Urls.accountSessionsLogoutPage(baseQueryURI, realm, stateChecker).toString();
 }
示例#12
0
 public String getLoginUpdateTotpUrl() {
   return Urls.loginActionUpdateTotp(baseURI, realm).toString();
 }
示例#13
0
 @Override
 protected URI getBaseRedirectUri() {
   return Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName());
 }
示例#14
0
 public String getRegistrationAction() {
   return Urls.realmRegisterAction(baseURI, realm).toString();
 }
示例#15
0
 public String getPasswordUrl() {
   return Urls.accountPasswordPage(baseQueryURI, realm).toString();
 }
示例#16
0
 public String getRegistrationUrl() {
   return Urls.realmRegisterPage(baseURI, realm).toString();
 }
示例#17
0
 public String getLoginEmailVerificationUrl() {
   return Urls.loginActionEmailVerification(baseURI, realm).toString();
 }
示例#18
0
 public String getLoginUsernameReminderUrl() {
   return Urls.loginUsernameReminder(baseURI, realm).toString();
 }
示例#19
0
 public String getLoginPasswordResetUrl() {
   return Urls.loginPasswordReset(baseURI, realm).toString();
 }
示例#20
0
 public String getLoginUpdateProfileUrl() {
   return Urls.loginActionUpdateProfile(baseURI, realm).toString();
 }
示例#21
0
 public String getResourcesPath() {
   URI uri = Urls.themeRoot(baseURI);
   return uri.getPath() + "/" + theme.getType().toString().toLowerCase() + "/" + theme.getName();
 }
示例#22
0
 public String getLoginUrl() {
   return Urls.realmLoginPage(baseURI, realm).toString();
 }
示例#23
0
 public String getLogUrl() {
   return Urls.accountLogPage(baseQueryURI, realm).toString();
 }
示例#24
0
  @Path("federated-identity-update")
  @GET
  public Response processFederatedIdentityUpdate(
      @QueryParam("action") String action,
      @QueryParam("provider_id") String providerId,
      @QueryParam("stateChecker") String stateChecker) {
    if (auth == null) {
      return login("identity");
    }

    require(AccountRoles.MANAGE_ACCOUNT);
    csrfCheck(stateChecker);
    UserModel user = auth.getUser();

    if (Validation.isEmpty(providerId)) {
      setReferrerOnPage();
      return account
          .setError(Messages.MISSING_IDENTITY_PROVIDER)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }
    AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action);
    if (accountSocialAction == null) {
      setReferrerOnPage();
      return account
          .setError(Messages.INVALID_FEDERATED_IDENTITY_ACTION)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    boolean hasProvider = false;

    for (IdentityProviderModel model : realm.getIdentityProviders()) {
      if (model.getAlias().equals(providerId)) {
        hasProvider = true;
      }
    }

    if (!hasProvider) {
      setReferrerOnPage();
      return account
          .setError(Messages.IDENTITY_PROVIDER_NOT_FOUND)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    if (!user.isEnabled()) {
      setReferrerOnPage();
      return account
          .setError(Messages.ACCOUNT_DISABLED)
          .createResponse(AccountPages.FEDERATED_IDENTITY);
    }

    switch (accountSocialAction) {
      case ADD:
        String redirectUri =
            UriBuilder.fromUri(
                    Urls.accountFederatedIdentityPage(uriInfo.getBaseUri(), realm.getName()))
                .build()
                .toString();

        try {
          ClientSessionModel clientSession = auth.getClientSession();
          ClientSessionCode clientSessionCode = new ClientSessionCode(realm, clientSession);
          clientSessionCode.setAction(ClientSessionModel.Action.AUTHENTICATE.name());
          clientSession.setRedirectUri(redirectUri);
          clientSession.setNote(OIDCLoginProtocol.STATE_PARAM, UUID.randomUUID().toString());

          return Response.temporaryRedirect(
                  Urls.identityProviderAuthnRequest(
                      this.uriInfo.getBaseUri(),
                      providerId,
                      realm.getName(),
                      clientSessionCode.getCode()))
              .build();
        } catch (Exception spe) {
          setReferrerOnPage();
          return account
              .setError(Messages.IDENTITY_PROVIDER_REDIRECT_ERROR)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      case REMOVE:
        FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
        if (link != null) {

          // Removing last social provider is not possible if you don't have other possibility to
          // authenticate
          if (session.users().getFederatedIdentities(user, realm).size() > 1
              || user.getFederationLink() != null
              || isPasswordSet(user)) {
            session.users().removeFederatedIdentity(realm, user, providerId);

            logger.debugv(
                "Social provider {0} removed successfully from user {1}",
                providerId, user.getUsername());

            event
                .event(EventType.REMOVE_FEDERATED_IDENTITY)
                .client(auth.getClient())
                .user(auth.getUser())
                .detail(Details.USERNAME, link.getUserId() + "@" + link.getIdentityProvider())
                .success();

            setReferrerOnPage();
            return account
                .setSuccess(Messages.IDENTITY_PROVIDER_REMOVED)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          } else {
            setReferrerOnPage();
            return account
                .setError(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER)
                .createResponse(AccountPages.FEDERATED_IDENTITY);
          }
        } else {
          setReferrerOnPage();
          return account
              .setError(Messages.FEDERATED_IDENTITY_NOT_ACTIVE)
              .createResponse(AccountPages.FEDERATED_IDENTITY);
        }
      default:
        throw new IllegalArgumentException();
    }
  }
示例#25
0
 public String getSessionsUrl() {
   return Urls.accountSessionsPage(baseQueryURI, realm).toString();
 }
示例#26
0
 public String getSocialUrl() {
   return Urls.accountFederatedIdentityPage(baseQueryURI, realm).toString();
 }
示例#27
0
 public String getLoginUpdatePasswordUrl() {
   return Urls.loginActionUpdatePassword(baseURI, realm).toString();
 }
/** @author <a href="mailto:[email protected]">Marek Posolda</a> */
public class AccountApplicationsPage extends AbstractAccountPage {

  private String path =
      Urls.accountApplicationsPage(UriBuilder.fromUri(Constants.AUTH_SERVER_ROOT).build(), "test")
          .toString();

  @Override
  public boolean isCurrent() {
    return driver.getTitle().contains("Account Management")
        && driver.getCurrentUrl().endsWith("/account/applications");
  }

  @Override
  public void open() {
    driver.navigate().to(path);
  }

  public void setPath(String path) {
    this.path = path;
  }

  public void revokeGrant(String clientId) {
    driver.findElement(By.id("revoke-" + clientId)).click();
  }

  public Map<String, AppEntry> getApplications() {
    Map<String, AppEntry> table = new HashMap<String, AppEntry>();
    for (WebElement r : driver.findElements(By.tagName("tr"))) {
      int count = 0;
      AppEntry currentEntry = null;

      for (WebElement col : r.findElements(By.tagName("td"))) {
        count++;
        switch (count) {
          case 1:
            currentEntry = new AppEntry();
            String client = col.getText();
            table.put(client, currentEntry);
            break;
          case 2:
            String rolesStr = col.getText();
            String[] roles = rolesStr.split(",");
            for (String role : roles) {
              role = role.trim();
              currentEntry.addAvailableRole(role);
            }
            break;
          case 3:
            rolesStr = col.getText();
            if (rolesStr.isEmpty()) break;
            roles = rolesStr.split(",");
            for (String role : roles) {
              role = role.trim();
              currentEntry.addGrantedRole(role);
            }
            break;
          case 4:
            String protMappersStr = col.getText();
            if (protMappersStr.isEmpty()) break;
            String[] protMappers = protMappersStr.split(",");
            for (String protMapper : protMappers) {
              protMapper = protMapper.trim();
              currentEntry.addMapper(protMapper);
            }
            break;
          case 5:
            String additionalGrant = col.getText();
            if (additionalGrant.isEmpty()) break;
            String[] grants = additionalGrant.split(",");
            for (String grant : grants) {
              grant = grant.trim();
              currentEntry.addAdditionalGrant(grant);
            }
            break;
        }
      }
    }
    table.remove("Application");
    return table;
  }

  public static class AppEntry {

    private final List<String> rolesAvailable = new ArrayList<String>();
    private final List<String> rolesGranted = new ArrayList<String>();
    private final List<String> protocolMappersGranted = new ArrayList<String>();
    private final List<String> additionalGrants = new ArrayList<>();

    private void addAvailableRole(String role) {
      rolesAvailable.add(role);
    }

    private void addGrantedRole(String role) {
      rolesGranted.add(role);
    }

    private void addMapper(String protocolMapper) {
      protocolMappersGranted.add(protocolMapper);
    }

    private void addAdditionalGrant(String grant) {
      additionalGrants.add(grant);
    }

    public List<String> getRolesGranted() {
      return rolesGranted;
    }

    public List<String> getRolesAvailable() {
      return rolesAvailable;
    }

    public List<String> getProtocolMappersGranted() {
      return protocolMappersGranted;
    }

    public List<String> getAdditionalGrants() {
      return additionalGrants;
    }
  }
}
示例#29
0
 public String getTotpUrl() {
   return Urls.accountTotpPage(baseQueryURI, realm).toString();
 }