Java Code Examples for org.keycloak.common.util.Base64Url#encode()

The following examples show how to use org.keycloak.common.util.Base64Url#encode() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AbstractIdentityProvider.java    From keycloak with Apache License 2.0 6 votes vote down vote up
protected String getLinkingUrl(UriInfo uriInfo, ClientModel authorizedClient, UserSessionModel tokenUserSession) {
    String provider = getConfig().getAlias();
    String clientId = authorizedClient.getClientId();
    String nonce = UUID.randomUUID().toString();
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
    String input = nonce + tokenUserSession.getId() + clientId + provider;
    byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
    String hash = Base64Url.encode(check);
    return KeycloakUriBuilder.fromUri(uriInfo.getBaseUri())
            .path("/realms/{realm}/broker/{provider}/link")
            .queryParam("nonce", nonce)
            .queryParam("hash", hash)
            .queryParam("client_id", clientId)
            .build(authorizedClient.getRealm().getName(), provider)
            .toString();
}
 
Example 2
Source File: TokenEndpoint.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String generateS256CodeChallenge(String codeVerifier) throws Exception {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(codeVerifier.getBytes("ISO_8859_1"));
    byte[] digestBytes = md.digest();
    String codeVerifierEncoded = Base64Url.encode(digestBytes);
    return codeVerifierEncoded;
}
 
Example 3
Source File: AuthenticationManager.java    From keycloak with Apache License 2.0 5 votes vote down vote up
public static IdentityCookieToken createIdentityToken(KeycloakSession keycloakSession, RealmModel realm, UserModel user, UserSessionModel session, String issuer) {
    IdentityCookieToken token = new IdentityCookieToken();
    token.id(KeycloakModelUtils.generateId());
    token.issuedNow();
    token.subject(user.getId());
    token.issuer(issuer);
    token.type(TokenUtil.TOKEN_TYPE_KEYCLOAK_ID);

    if (session != null) {
        token.setSessionState(session.getId());
    }

    if (session != null && session.isRememberMe() && realm.getSsoSessionMaxLifespanRememberMe() > 0) {
        token.expiration(Time.currentTime() + realm.getSsoSessionMaxLifespanRememberMe());
    } else if (realm.getSsoSessionMaxLifespan() > 0) {
        token.expiration(Time.currentTime() + realm.getSsoSessionMaxLifespan());
    }

    String stateChecker = (String) keycloakSession.getAttribute("state_checker");
    if (stateChecker == null) {
        stateChecker = Base64Url.encode(KeycloakModelUtils.generateSecret());
        keycloakSession.setAttribute("state_checker", stateChecker);
    }
    token.getOtherClaims().put("state_checker", stateChecker);

    return token;
}
 
Example 4
Source File: CodeGenerateUtil.java    From keycloak with Apache License 2.0 5 votes vote down vote up
@Override
public String retrieveCode(KeycloakSession session, AuthenticationSessionModel authSession) {
    String nextCode = authSession.getAuthNote(ACTIVE_CODE);
    if (nextCode == null) {
        String actionId = Base64Url.encode(KeycloakModelUtils.generateSecret());
        authSession.setAuthNote(ACTIVE_CODE, actionId);
        nextCode = actionId;
    } else {
        logger.debug("Code already generated for authentication session, using same code");
    }

    return nextCode;
}
 
Example 5
Source File: WelcomeResource.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String setCsrfCookie() {
    String stateChecker = Base64Url.encode(KeycloakModelUtils.generateSecret());
    String cookiePath = session.getContext().getUri().getPath();
    boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
    CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true);
    return stateChecker;
}
 
Example 6
Source File: SerializedBrokeredIdentityContext.java    From keycloak with Apache License 2.0 5 votes vote down vote up
@JsonIgnore
@Override
public void setAttribute(String key, List<String> value) {
    try {
        byte[] listBytes = JsonSerialization.writeValueAsBytes(value);
        String listStr = Base64Url.encode(listBytes);
        ContextDataEntry ctxEntry = ContextDataEntry.create(List.class.getName(), listStr);
        this.contextData.put(Constants.USER_ATTRIBUTES_PREFIX + key, ctxEntry);
    } catch (IOException ioe) {
        throw new RuntimeException(ioe);
    }
}
 
Example 7
Source File: QuarkusWelcomeResource.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String setCsrfCookie() {
    String stateChecker = Base64Url.encode(KeycloakModelUtils.generateSecret());
    String cookiePath = session.getContext().getUri().getPath();
    boolean secureOnly = session.getContext().getUri().getRequestUri().getScheme().equalsIgnoreCase("https");
    CookieHelper.addCookie(KEYCLOAK_STATE_CHECKER, stateChecker, cookiePath, null, null, 300, secureOnly, true);
    return stateChecker;
}
 
Example 8
Source File: MtlsHoKTokenUtil.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private static String getCertificateThumbprintInSHA256DERX509Base64UrlEncoded (X509Certificate cert) throws NoSuchAlgorithmException, CertificateEncodingException {
    // need to calculate over DER encoding of the X.509 certificate
    //   https://tools.ietf.org/html/draft-ietf-oauth-mtls-08#section-3.1
    // in order to do that, call getEncoded()
    //   https://docs.oracle.com/javase/8/docs/api/java/security/cert/Certificate.html#getEncoded--
    byte[] DERX509Hash = cert.getEncoded();
    MessageDigest md = MessageDigest.getInstance(DIGEST_ALG);
    md.update(DERX509Hash);
    String DERX509Base64UrlEncoded = Base64Url.encode(md.digest());
    return DERX509Base64UrlEncoded;
}
 
Example 9
Source File: PkceGenerator.java    From keycloak with Apache License 2.0 5 votes vote down vote up
private String generateS256CodeChallenge(String codeVerifier) {
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(codeVerifier.getBytes("ISO_8859_1"));
        byte[] digestBytes = md.digest();
        String codeChallenge = Base64Url.encode(digestBytes);
        return codeChallenge;
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
 
Example 10
Source File: JWE.java    From keycloak with Apache License 2.0 5 votes vote down vote up
public String encodeJwe(JWEAlgorithmProvider algorithmProvider, JWEEncryptionProvider encryptionProvider) throws JWEException {
    try {
        if (header == null) {
            throw new IllegalStateException("Header must be set");
        }
        if (content == null) {
            throw new IllegalStateException("Content must be set");
        }

        if (algorithmProvider == null) {
            throw new IllegalArgumentException("No provider for alg '" + header.getAlgorithm() + "'");
        }

        if (encryptionProvider == null) {
            throw new IllegalArgumentException("No provider for enc '" + header.getEncryptionAlgorithm() + "'");
        }

        keyStorage.setEncryptionProvider(encryptionProvider);
        keyStorage.getCEKKey(JWEKeyStorage.KeyUse.ENCRYPTION, true); // Will generate CEK if it's not already present

        byte[] encodedCEK = algorithmProvider.encodeCek(encryptionProvider, keyStorage, keyStorage.getEncryptionKey());
        base64Cek = Base64Url.encode(encodedCEK);

        encryptionProvider.encodeJwe(this);

        return getEncodedJweString();
    } catch (Exception e) {
        throw new JWEException(e);
    }
}
 
Example 11
Source File: KeycloakLinkedAccountsProvider.java    From apicurio-studio with Apache License 2.0 5 votes vote down vote up
/**
 * @see io.apicurio.hub.api.security.ILinkedAccountsProvider#initiateLinkedAccount(io.apicurio.hub.core.beans.LinkedAccountType, java.lang.String, java.lang.String)
 */
@Override
public InitiatedLinkedAccount initiateLinkedAccount(LinkedAccountType accountType, String redirectUri,
        String nonce) {
    String authServerRootUrl = config.getKeycloakAuthUrl();
    String realm = config.getKeycloakRealm();
    String provider = accountType.alias();

    KeycloakSecurityContext session = (KeycloakSecurityContext) request.getAttribute(KeycloakSecurityContext.class.getName());
    AccessToken token = session.getToken();

    String clientId = token.getIssuedFor();
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("SHA-256");
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
    String input = nonce + token.getSessionState() + clientId + provider;
    byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
    String hash = Base64Url.encode(check);
    String accountLinkUrl = KeycloakUriBuilder.fromUri(authServerRootUrl)
        .path("/realms/{realm}/broker/{provider}/link").queryParam("nonce", nonce)
        .queryParam("hash", hash).queryParam("client_id", clientId)
        .queryParam("redirect_uri", redirectUri).build(realm, provider).toString();

    logger.debug("Account Link URL: {}", accountLinkUrl);

    // Return the URL that the browser should use to initiate the account linking
    InitiatedLinkedAccount rval = new InitiatedLinkedAccount();
    rval.setAuthUrl(accountLinkUrl);
    rval.setNonce(nonce);
    return rval;
}
 
Example 12
Source File: HashUtils.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public static String encodeHashToOIDC(byte[] hash) {
    int hashLength = hash.length / 2;
    byte[] hashInput = Arrays.copyOf(hash, hashLength);

    return Base64Url.encode(hashInput);
}
 
Example 13
Source File: TokenEndpoint.java    From keycloak with Apache License 2.0 4 votes vote down vote up
protected Response exchangeClientToSAML2Client(UserModel targetUser, UserSessionModel targetUserSession, String requestedTokenType,
                                              ClientModel targetClient, String audience, String scope) {
    // Create authSession with target SAML 2.0 client and authenticated user
    LoginProtocolFactory factory = (LoginProtocolFactory) session.getKeycloakSessionFactory()
            .getProviderFactory(LoginProtocol.class, SamlProtocol.LOGIN_PROTOCOL);
    SamlService samlService = (SamlService) factory.createProtocolEndpoint(realm, event);
    ResteasyProviderFactory.getInstance().injectProperties(samlService);
    AuthenticationSessionModel authSession = samlService.getOrCreateLoginSessionForIdpInitiatedSso(session, realm,
            targetClient, null);
    if (authSession == null) {
        logger.error("SAML assertion consumer url not set up");
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_CLIENT, "Client requires assertion consumer url set up", Response.Status.BAD_REQUEST);
    }

    authSession.setAuthenticatedUser(targetUser);

    event.session(targetUserSession);

    AuthenticationManager.setClientScopesInSession(authSession);
    ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(this.session, targetUserSession,
            authSession);

    updateUserSessionFromClientAuth(targetUserSession);

    // Create SAML 2.0 Assertion Response
    SamlClient samlClient = new SamlClient(targetClient);
    SamlProtocol samlProtocol = new TokenExchangeSamlProtocol(samlClient).setEventBuilder(event).setHttpHeaders(headers).setRealm(realm)
            .setSession(session).setUriInfo(session.getContext().getUri());

    Response samlAssertion = samlProtocol.authenticated(authSession, targetUserSession, clientSessionCtx);
    if (samlAssertion.getStatus() != 200) {
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Can not get SAML 2.0 token", Response.Status.BAD_REQUEST);
    }
    String xmlString = (String) samlAssertion.getEntity();
    String encodedXML = Base64Url.encode(xmlString.getBytes(GeneralConstants.SAML_CHARSET));

    int assertionLifespan = samlClient.getAssertionLifespan();

    AccessTokenResponse res = new AccessTokenResponse();
    res.setToken(encodedXML);
    res.setTokenType("Bearer");
    res.setExpiresIn(assertionLifespan <= 0 ? realm.getAccessCodeLifespan() : assertionLifespan);
    res.setOtherClaims(OAuth2Constants.ISSUED_TOKEN_TYPE, requestedTokenType);

    event.detail(Details.AUDIENCE, targetClient.getClientId());
    event.success();

    return cors.builder(Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).build();
}
 
Example 14
Source File: CredentialPublicKeyConverter.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public String convertToDatabaseColumn(COSEKey credentialPublicKey) {
    return Base64Url.encode(cborConverter.writeValueAsBytes(credentialPublicKey));
}
 
Example 15
Source File: WebAuthnRegister.java    From keycloak with Apache License 2.0 4 votes vote down vote up
@Override
public void requiredActionChallenge(RequiredActionContext context) {
    UserModel userModel = context.getUser();
    // Use standard UTF-8 charset to get bytes from string.
    // Otherwise the platform's default charset is used and it might cause problems later when
    // decoded on different system.
    String userId = Base64Url.encode(userModel.getId().getBytes(StandardCharsets.UTF_8));
    String username = userModel.getUsername();
    Challenge challenge = new DefaultChallenge();
    String challengeValue = Base64Url.encode(challenge.getValue());
    context.getAuthenticationSession().setAuthNote(WebAuthnConstants.AUTH_CHALLENGE_NOTE, challengeValue);

    // construct parameters for calling WebAuthn API navigator.credential.create()

    // mandatory
    WebAuthnPolicy policy = getWebAuthnPolicy(context);
    List<String> signatureAlgorithmsList = policy.getSignatureAlgorithm();
    String signatureAlgorithms = stringifySignatureAlgorithms(signatureAlgorithmsList);
    String rpEntityName = policy.getRpEntityName();

    // optional
    String rpId = policy.getRpId();
    if (rpId == null || rpId.isEmpty()) rpId =  context.getUriInfo().getBaseUri().getHost();
    String attestationConveyancePreference = policy.getAttestationConveyancePreference();
    String authenticatorAttachment = policy.getAuthenticatorAttachment();
    String requireResidentKey = policy.getRequireResidentKey();
    String userVerificationRequirement = policy.getUserVerificationRequirement();
    long createTimeout = policy.getCreateTimeout();
    boolean avoidSameAuthenticatorRegister = policy.isAvoidSameAuthenticatorRegister();

    String excludeCredentialIds = "";
    if (avoidSameAuthenticatorRegister) {
        List<CredentialModel> webAuthnCredentials = session.userCredentialManager().getStoredCredentialsByType(context.getRealm(), userModel, getCredentialType());
        List<String> webAuthnCredentialPubKeyIds = webAuthnCredentials.stream().map(credentialModel -> {

            WebAuthnCredentialModel credModel = WebAuthnCredentialModel.createFromCredentialModel(credentialModel);
            return Base64Url.encodeBase64ToBase64Url(credModel.getWebAuthnCredentialData().getCredentialId());

        }).collect(Collectors.toList());

        excludeCredentialIds = stringifyExcludeCredentialIds(webAuthnCredentialPubKeyIds);
    }

    String isSetRetry = context.getHttpRequest().getDecodedFormParameters().getFirst(WebAuthnConstants.IS_SET_RETRY);

    Response form = context.form()
            .setAttribute(WebAuthnConstants.CHALLENGE, challengeValue)
            .setAttribute(WebAuthnConstants.USER_ID, userId)
            .setAttribute(WebAuthnConstants.USER_NAME, username)
            .setAttribute(WebAuthnConstants.RP_ENTITY_NAME, rpEntityName)
            .setAttribute(WebAuthnConstants.SIGNATURE_ALGORITHMS, signatureAlgorithms)
            .setAttribute(WebAuthnConstants.RP_ID, rpId)
            .setAttribute(WebAuthnConstants.ATTESTATION_CONVEYANCE_PREFERENCE, attestationConveyancePreference)
            .setAttribute(WebAuthnConstants.AUTHENTICATOR_ATTACHMENT, authenticatorAttachment)
            .setAttribute(WebAuthnConstants.REQUIRE_RESIDENT_KEY, requireResidentKey)
            .setAttribute(WebAuthnConstants.USER_VERIFICATION_REQUIREMENT, userVerificationRequirement)
            .setAttribute(WebAuthnConstants.CREATE_TIMEOUT, createTimeout)
            .setAttribute(WebAuthnConstants.EXCLUDE_CREDENTIAL_IDS, excludeCredentialIds)
            .setAttribute(WebAuthnConstants.IS_SET_RETRY, isSetRetry)
            .createForm("webauthn-register.ftl");
    context.challenge(form);
}
 
Example 16
Source File: WebAuthnAuthenticator.java    From keycloak with Apache License 2.0 4 votes vote down vote up
public void action(AuthenticationFlowContext context) {
    MultivaluedMap<String, String> params = context.getHttpRequest().getDecodedFormParameters();

    context.getEvent().detail(Details.CREDENTIAL_TYPE, getCredentialType());

    // receive error from navigator.credentials.get()
    String errorMsgFromWebAuthnApi = params.getFirst(WebAuthnConstants.ERROR);
    if (errorMsgFromWebAuthnApi != null && !errorMsgFromWebAuthnApi.isEmpty()) {
        setErrorResponse(context, WEBAUTHN_ERROR_API_GET, errorMsgFromWebAuthnApi);
        return;
    }

    String baseUrl = UriUtils.getOrigin(context.getUriInfo().getBaseUri());
    String rpId = getRpID(context);

    Origin origin = new Origin(baseUrl);
    Challenge challenge = new DefaultChallenge(context.getAuthenticationSession().getAuthNote(WebAuthnConstants.AUTH_CHALLENGE_NOTE));
    ServerProperty server = new ServerProperty(origin, rpId, challenge, null);

    byte[] credentialId = Base64Url.decode(params.getFirst(WebAuthnConstants.CREDENTIAL_ID));
    byte[] clientDataJSON = Base64Url.decode(params.getFirst(WebAuthnConstants.CLIENT_DATA_JSON));
    byte[] authenticatorData = Base64Url.decode(params.getFirst(WebAuthnConstants.AUTHENTICATOR_DATA));
    byte[] signature = Base64Url.decode(params.getFirst(WebAuthnConstants.SIGNATURE));

    final String userHandle = params.getFirst(WebAuthnConstants.USER_HANDLE);
    final String userId;
    // existing User Handle means that the authenticator used Resident Key supported public key credential
    if (userHandle == null || userHandle.isEmpty()) {
        // Resident Key not supported public key credential was used
        // so rely on the user that has already been authenticated
        userId = context.getUser().getId();
    } else {
        // decode using the same charset as it has been encoded (see: WebAuthnRegister.java)
        userId = new String(Base64Url.decode(userHandle), StandardCharsets.UTF_8);
        if (context.getUser() != null) {
            // Resident Key supported public key credential was used,
            // so need to confirm whether the already authenticated user is equals to one authenticated by the webauthn authenticator
            String firstAuthenticatedUserId = context.getUser().getId();
            if (firstAuthenticatedUserId != null && !firstAuthenticatedUserId.equals(userId)) {
                context.getEvent()
                        .detail("first_authenticated_user_id", firstAuthenticatedUserId)
                        .detail("web_authn_authenticator_authenticated_user_id", userId);
                setErrorResponse(context, WEBAUTHN_ERROR_DIFFERENT_USER, null);
                return;
            }
        } else {
            // Resident Key supported public key credential was used,
            // and the user has not yet been identified
            // so rely on the user authenticated by the webauthn authenticator
            // NOP
        }
    }

    boolean isUVFlagChecked = false;
    String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
    if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;

    UserModel user = session.users().getUserById(userId, context.getRealm());

    AuthenticationRequest authenticationRequest = new AuthenticationRequest(
            credentialId,
            authenticatorData,
            clientDataJSON,
            signature
            );

    AuthenticationParameters authenticationParameters = new AuthenticationParameters(
            server,
            null, // here authenticator cannot be fetched, set it afterwards in WebAuthnCredentialProvider.isValid()
            isUVFlagChecked
            );

    WebAuthnCredentialModelInput cred = new WebAuthnCredentialModelInput(getCredentialType());

    cred.setAuthenticationRequest(authenticationRequest);
    cred.setAuthenticationParameters(authenticationParameters);

    boolean result = false;
    try {
        result = session.userCredentialManager().isValid(context.getRealm(), user, cred);
    } catch (WebAuthnException wae) {
        setErrorResponse(context, WEBAUTHN_ERROR_AUTH_VERIFICATION, wae.getMessage());
        return;
    }
    String encodedCredentialID = Base64Url.encode(credentialId);
    if (result) {
        String isUVChecked = Boolean.toString(isUVFlagChecked);
        logger.debugv("WebAuthn Authentication successed. isUserVerificationChecked = {0}, PublicKeyCredentialID = {1}", isUVChecked, encodedCredentialID);
        context.setUser(user);
        context.getEvent()
            .detail("web_authn_authenticator_user_verification_checked", isUVChecked)
            .detail("public_key_credential_id", encodedCredentialID);
        context.success();
    } else {
        context.getEvent()
            .detail("web_authn_authenticated_user_id", userId)
            .detail("public_key_credential_id", encodedCredentialID);
        setErrorResponse(context, WEBAUTHN_ERROR_USER_NOT_FOUND, null);
        context.cancelLogin();
    }
}
 
Example 17
Source File: AdminController.java    From keycloak with Apache License 2.0 4 votes vote down vote up
@RequestMapping(path = "/LinkServlet", method = RequestMethod.GET)
    public String tokenController(WebRequest webRequest,
                                  @RequestParam Map<String, String> attributes,
                                  Model model) {

        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession httpSession = attr.getRequest().getSession(true);

//        response.addHeader("Cache-Control", "no-cache");

        String responseAttr = attributes.get("response");

        if (StringUtils.isEmpty(responseAttr)) {
            String provider = attributes.get("provider");
            String realm = attributes.get("realm");
            KeycloakSecurityContext keycloakSession =
                    (KeycloakSecurityContext) webRequest.getAttribute(
                            KeycloakSecurityContext.class.getName(),
                            RequestAttributes.SCOPE_REQUEST);
            AccessToken token = keycloakSession.getToken();
            String clientId = token.getIssuedFor();
            String nonce = UUID.randomUUID().toString();
            MessageDigest md;
            try {
                md = MessageDigest.getInstance("SHA-256");
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            }
            String input = nonce + token.getSessionState() + clientId + provider;
            byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
            String hash = Base64Url.encode(check);
            httpSession.setAttribute("hash", hash);
            String redirectUri = KeycloakUriBuilder.fromUri("http://localhost:8280/admin/LinkServlet")
                    .queryParam("response", "true").build().toString();
            String accountLinkUrl = KeycloakUriBuilder.fromUri("http://localhost:8180/")
                    .path("/auth/realms/{realm}/broker/{provider}/link")
                    .queryParam("nonce", nonce)
                    .queryParam("hash", hash)
                    .queryParam("client_id", token.getIssuedFor())
                    .queryParam("redirect_uri", redirectUri).build(realm, provider).toString();

            return "redirect:" + accountLinkUrl;
        } else {
            String error = attributes.get("link_error");
            if (StringUtils.isEmpty(error))
                model.addAttribute("error", "Account linked");
            else
                model.addAttribute("error", error);

            return "linking";
        }
    }
 
Example 18
Source File: AccountFormService.java    From keycloak with Apache License 2.0 4 votes vote down vote up
@Path("identity")
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response processFederatedIdentityUpdate(final MultivaluedMap<String, String> formData) {
    if (auth == null) {
        return login("identity");
    }

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

    String action = formData.getFirst("action");
    String providerId = formData.getFirst("providerId");

    if (Validation.isEmpty(providerId)) {
        setReferrerOnPage();
        return account.setError(Status.OK, Messages.MISSING_IDENTITY_PROVIDER).createResponse(AccountPages.FEDERATED_IDENTITY);
    }
    AccountSocialAction accountSocialAction = AccountSocialAction.getAction(action);
    if (accountSocialAction == null) {
        setReferrerOnPage();
        return account.setError(Status.OK, 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(Status.OK, Messages.IDENTITY_PROVIDER_NOT_FOUND).createResponse(AccountPages.FEDERATED_IDENTITY);
    }

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

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

            try {
                String nonce = UUID.randomUUID().toString();
                MessageDigest md = MessageDigest.getInstance("SHA-256");
                String input = nonce + auth.getSession().getId() + client.getClientId() + providerId;
                byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
                String hash = Base64Url.encode(check);
                URI linkUrl = Urls.identityProviderLinkRequest(this.session.getContext().getUri().getBaseUri(), providerId, realm.getName());
                linkUrl = UriBuilder.fromUri(linkUrl)
                        .queryParam("nonce", nonce)
                        .queryParam("hash", hash)
                        .queryParam("client_id", client.getClientId())
                        .queryParam("redirect_uri", redirectUri)
                        .build();
                return Response.seeOther(linkUrl)
                        .build();
            } catch (Exception spe) {
                setReferrerOnPage();
                return account.setError(Response.Status.INTERNAL_SERVER_ERROR, 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(session, realm, 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, auth.getUser().getUsername())
                            .detail(Details.IDENTITY_PROVIDER, link.getIdentityProvider())
                            .detail(Details.IDENTITY_PROVIDER_USERNAME, link.getUserName())
                            .success();

                    setReferrerOnPage();
                    return account.setSuccess(Messages.IDENTITY_PROVIDER_REMOVED).createResponse(AccountPages.FEDERATED_IDENTITY);
                } else {
                    setReferrerOnPage();
                    return account.setError(Status.OK, Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER).createResponse(AccountPages.FEDERATED_IDENTITY);
                }
            } else {
                setReferrerOnPage();
                return account.setError(Status.OK, Messages.FEDERATED_IDENTITY_NOT_ACTIVE).createResponse(AccountPages.FEDERATED_IDENTITY);
            }
        default:
            throw new IllegalArgumentException();
    }
}
 
Example 19
Source File: LinkedAccountsResource.java    From keycloak with Apache License 2.0 4 votes vote down vote up
@GET
@Path("/{providerId}")
@Produces(MediaType.APPLICATION_JSON)
@Deprecated
public Response buildLinkedAccountURI(@PathParam("providerId") String providerId, 
                                 @QueryParam("redirectUri") String redirectUri) {
    auth.require(AccountRoles.MANAGE_ACCOUNT);
    
    if (redirectUri == null) {
        ErrorResponse.error(Messages.INVALID_REDIRECT_URI, Response.Status.BAD_REQUEST);
    }
    
    String errorMessage = checkCommonPreconditions(providerId);
    if (errorMessage != null) {
        return ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
    }
    
    try {
        String nonce = UUID.randomUUID().toString();
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        String input = nonce + auth.getSession().getId() +  ACCOUNT_CONSOLE_CLIENT_ID + providerId;
        byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
        String hash = Base64Url.encode(check);
        URI linkUri = Urls.identityProviderLinkRequest(this.session.getContext().getUri().getBaseUri(), providerId, realm.getName());
        linkUri = UriBuilder.fromUri(linkUri)
                .queryParam("nonce", nonce)
                .queryParam("hash", hash)
                // need to use "account-console" client because IdentityBrokerService authenticates user using cookies
                // the regular "account" client is used only for REST calls therefore cookies authentication cannot be used
                .queryParam("client_id", ACCOUNT_CONSOLE_CLIENT_ID)
                .queryParam("redirect_uri", redirectUri)
                .build();
        
        AccountLinkUriRepresentation rep = new AccountLinkUriRepresentation();
        rep.setAccountLinkUri(linkUri);
        rep.setHash(hash);
        rep.setNonce(nonce);
        
        return Cors.add(request, Response.ok(rep)).auth().allowedOrigins(auth.getToken()).build();
    } catch (Exception spe) {
        spe.printStackTrace();
        return ErrorResponse.error(Messages.FAILED_TO_PROCESS_RESPONSE, Response.Status.INTERNAL_SERVER_ERROR);
    }
}
 
Example 20
Source File: WebAuthn4jAuthenticatorTest.java    From keycloak-webauthn-authenticator with Apache License 2.0 4 votes vote down vote up
private String getRandomString(int sizeInByte) {
    return Base64Url.encode(KeycloakModelUtils.generateSecret(sizeInByte));
}