Search in sources :

Example 1 with VaultStringSecret

use of org.keycloak.vault.VaultStringSecret in project keycloak by keycloak.

the class OIDCIdentityProvider method exchangeSessionToken.

@Override
protected Response exchangeSessionToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
    String refreshToken = tokenUserSession.getNote(FEDERATED_REFRESH_TOKEN);
    String accessToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
    String idToken = tokenUserSession.getNote(FEDERATED_ID_TOKEN);
    if (accessToken == null) {
        event.detail(Details.REASON, "requested_issuer is not linked");
        event.error(Errors.INVALID_TOKEN);
        return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
    }
    try (VaultStringSecret vaultStringSecret = session.vault().getStringSecret(getConfig().getClientSecret())) {
        long expiration = Long.parseLong(tokenUserSession.getNote(FEDERATED_TOKEN_EXPIRATION));
        if (expiration == 0 || expiration > Time.currentTime()) {
            AccessTokenResponse tokenResponse = new AccessTokenResponse();
            tokenResponse.setExpiresIn(expiration);
            tokenResponse.setToken(accessToken);
            tokenResponse.setIdToken(null);
            tokenResponse.setRefreshToken(null);
            tokenResponse.setRefreshExpiresIn(0);
            tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
            tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
            event.success();
            return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
        }
        String response = getRefreshTokenRequest(session, refreshToken, getConfig().getClientId(), vaultStringSecret.get().orElse(getConfig().getClientSecret())).asString();
        if (response.contains("error")) {
            logger.debugv("Error refreshing token, refresh token expiration?: {0}", response);
            event.detail(Details.REASON, "requested_issuer token expired");
            event.error(Errors.INVALID_TOKEN);
            return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
        }
        AccessTokenResponse newResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
        long accessTokenExpiration = newResponse.getExpiresIn() > 0 ? Time.currentTime() + newResponse.getExpiresIn() : 0;
        tokenUserSession.setNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(accessTokenExpiration));
        tokenUserSession.setNote(FEDERATED_REFRESH_TOKEN, newResponse.getRefreshToken());
        tokenUserSession.setNote(FEDERATED_ACCESS_TOKEN, newResponse.getToken());
        tokenUserSession.setNote(FEDERATED_ID_TOKEN, newResponse.getIdToken());
        newResponse.setIdToken(null);
        newResponse.setRefreshToken(null);
        newResponse.setRefreshExpiresIn(0);
        newResponse.getOtherClaims().clear();
        newResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
        newResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
        event.success();
        return Response.ok(newResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : VaultStringSecret(org.keycloak.vault.VaultStringSecret) IOException(java.io.IOException) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 2 with VaultStringSecret

use of org.keycloak.vault.VaultStringSecret in project keycloak by keycloak.

the class TwitterIdentityProvider method performLogin.

@Override
public Response performLogin(AuthenticationRequest request) {
    try (VaultStringSecret vaultStringSecret = session.vault().getStringSecret(getConfig().getClientSecret())) {
        Twitter twitter = new TwitterFactory().getInstance();
        twitter.setOAuthConsumer(getConfig().getClientId(), vaultStringSecret.get().orElse(getConfig().getClientSecret()));
        URI uri = new URI(request.getRedirectUri() + "?state=" + request.getState().getEncoded());
        RequestToken requestToken = twitter.getOAuthRequestToken(uri.toString());
        AuthenticationSessionModel authSession = request.getAuthenticationSession();
        authSession.setAuthNote(TWITTER_TOKEN, requestToken.getToken());
        authSession.setAuthNote(TWITTER_TOKENSECRET, requestToken.getTokenSecret());
        URI authenticationUrl = URI.create(requestToken.getAuthenticationURL());
        return Response.seeOther(authenticationUrl).build();
    } catch (Exception e) {
        throw new IdentityBrokerException("Could send authentication request to twitter.", e);
    }
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) VaultStringSecret(org.keycloak.vault.VaultStringSecret) RequestToken(twitter4j.auth.RequestToken) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) Twitter(twitter4j.Twitter) TwitterFactory(twitter4j.TwitterFactory) URI(java.net.URI) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) WebApplicationException(javax.ws.rs.WebApplicationException)

Example 3 with VaultStringSecret

use of org.keycloak.vault.VaultStringSecret in project keycloak by keycloak.

the class DefaultEmailSenderProvider method send.

@Override
public void send(Map<String, String> config, UserModel user, String subject, String textBody, String htmlBody) throws EmailException {
    Transport transport = null;
    try {
        String address = retrieveEmailAddress(user);
        Properties props = new Properties();
        if (config.containsKey("host")) {
            props.setProperty("mail.smtp.host", config.get("host"));
        }
        boolean auth = "true".equals(config.get("auth"));
        boolean ssl = "true".equals(config.get("ssl"));
        boolean starttls = "true".equals(config.get("starttls"));
        if (config.containsKey("port") && config.get("port") != null) {
            props.setProperty("mail.smtp.port", config.get("port"));
        }
        if (auth) {
            props.setProperty("mail.smtp.auth", "true");
        }
        if (ssl) {
            props.setProperty("mail.smtp.ssl.enable", "true");
        }
        if (starttls) {
            props.setProperty("mail.smtp.starttls.enable", "true");
        }
        if (ssl || starttls) {
            props.put("mail.smtp.ssl.protocols", SUPPORTED_SSL_PROTOCOLS);
            setupTruststore(props);
        }
        props.setProperty("mail.smtp.timeout", "10000");
        props.setProperty("mail.smtp.connectiontimeout", "10000");
        String from = config.get("from");
        String fromDisplayName = config.get("fromDisplayName");
        String replyTo = config.get("replyTo");
        String replyToDisplayName = config.get("replyToDisplayName");
        String envelopeFrom = config.get("envelopeFrom");
        Session session = Session.getInstance(props);
        Multipart multipart = new MimeMultipart("alternative");
        if (textBody != null) {
            MimeBodyPart textPart = new MimeBodyPart();
            textPart.setText(textBody, "UTF-8");
            multipart.addBodyPart(textPart);
        }
        if (htmlBody != null) {
            MimeBodyPart htmlPart = new MimeBodyPart();
            htmlPart.setContent(htmlBody, "text/html; charset=UTF-8");
            multipart.addBodyPart(htmlPart);
        }
        SMTPMessage msg = new SMTPMessage(session);
        msg.setFrom(toInternetAddress(from, fromDisplayName));
        msg.setReplyTo(new Address[] { toInternetAddress(from, fromDisplayName) });
        if (replyTo != null && !replyTo.isEmpty()) {
            msg.setReplyTo(new Address[] { toInternetAddress(replyTo, replyToDisplayName) });
        }
        if (envelopeFrom != null && !envelopeFrom.isEmpty()) {
            msg.setEnvelopeFrom(envelopeFrom);
        }
        msg.setHeader("To", address);
        msg.setSubject(subject, "utf-8");
        msg.setContent(multipart);
        msg.saveChanges();
        msg.setSentDate(new Date());
        transport = session.getTransport("smtp");
        if (auth) {
            try (VaultStringSecret vaultStringSecret = this.session.vault().getStringSecret(config.get("password"))) {
                transport.connect(config.get("user"), vaultStringSecret.get().orElse(config.get("password")));
            }
        } else {
            transport.connect();
        }
        transport.sendMessage(msg, new InternetAddress[] { new InternetAddress(address) });
    } catch (Exception e) {
        ServicesLogger.LOGGER.failedToSendEmail(e);
        throw new EmailException(e);
    } finally {
        if (transport != null) {
            try {
                transport.close();
            } catch (MessagingException e) {
                logger.warn("Failed to close transport", e);
            }
        }
    }
}
Also used : Multipart(javax.mail.Multipart) MimeMultipart(javax.mail.internet.MimeMultipart) SMTPMessage(com.sun.mail.smtp.SMTPMessage) InternetAddress(javax.mail.internet.InternetAddress) VaultStringSecret(org.keycloak.vault.VaultStringSecret) MessagingException(javax.mail.MessagingException) Properties(java.util.Properties) Date(java.util.Date) MessagingException(javax.mail.MessagingException) AddressException(javax.mail.internet.AddressException) KeyManagementException(java.security.KeyManagementException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) MimeMultipart(javax.mail.internet.MimeMultipart) Transport(javax.mail.Transport) MimeBodyPart(javax.mail.internet.MimeBodyPart) KeycloakSession(org.keycloak.models.KeycloakSession) Session(javax.mail.Session)

Example 4 with VaultStringSecret

use of org.keycloak.vault.VaultStringSecret in project keycloak by keycloak.

the class OIDCIdentityProvider method exchangeStoredToken.

@Override
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
    FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
    if (model == null || model.getToken() == null) {
        event.detail(Details.REASON, "requested_issuer is not linked");
        event.error(Errors.INVALID_TOKEN);
        return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
    }
    try (VaultStringSecret vaultStringSecret = session.vault().getStringSecret(getConfig().getClientSecret())) {
        String modelTokenString = model.getToken();
        AccessTokenResponse tokenResponse = JsonSerialization.readValue(modelTokenString, AccessTokenResponse.class);
        Integer exp = (Integer) tokenResponse.getOtherClaims().get(ACCESS_TOKEN_EXPIRATION);
        if (exp != null && exp < Time.currentTime()) {
            if (tokenResponse.getRefreshToken() == null) {
                return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
            }
            String response = getRefreshTokenRequest(session, tokenResponse.getRefreshToken(), getConfig().getClientId(), vaultStringSecret.get().orElse(getConfig().getClientSecret())).asString();
            if (response.contains("error")) {
                logger.debugv("Error refreshing token, refresh token expiration?: {0}", response);
                model.setToken(null);
                session.users().updateFederatedIdentity(authorizedClient.getRealm(), tokenSubject, model);
                event.detail(Details.REASON, "requested_issuer token expired");
                event.error(Errors.INVALID_TOKEN);
                return exchangeTokenExpired(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
            }
            AccessTokenResponse newResponse = JsonSerialization.readValue(response, AccessTokenResponse.class);
            if (newResponse.getExpiresIn() > 0) {
                int accessTokenExpiration = Time.currentTime() + (int) newResponse.getExpiresIn();
                newResponse.getOtherClaims().put(ACCESS_TOKEN_EXPIRATION, accessTokenExpiration);
            }
            if (newResponse.getRefreshToken() == null && tokenResponse.getRefreshToken() != null) {
                newResponse.setRefreshToken(tokenResponse.getRefreshToken());
                newResponse.setRefreshExpiresIn(tokenResponse.getRefreshExpiresIn());
            }
            response = JsonSerialization.writeValueAsString(newResponse);
            String oldToken = tokenUserSession.getNote(FEDERATED_ACCESS_TOKEN);
            if (oldToken != null && oldToken.equals(tokenResponse.getToken())) {
                int accessTokenExpiration = newResponse.getExpiresIn() > 0 ? Time.currentTime() + (int) newResponse.getExpiresIn() : 0;
                tokenUserSession.setNote(FEDERATED_TOKEN_EXPIRATION, Long.toString(accessTokenExpiration));
                tokenUserSession.setNote(FEDERATED_REFRESH_TOKEN, newResponse.getRefreshToken());
                tokenUserSession.setNote(FEDERATED_ACCESS_TOKEN, newResponse.getToken());
                tokenUserSession.setNote(FEDERATED_ID_TOKEN, newResponse.getIdToken());
            }
            model.setToken(response);
            tokenResponse = newResponse;
        } else if (exp != null) {
            tokenResponse.setExpiresIn(exp - Time.currentTime());
        }
        tokenResponse.setIdToken(null);
        tokenResponse.setRefreshToken(null);
        tokenResponse.setRefreshExpiresIn(0);
        tokenResponse.getOtherClaims().clear();
        tokenResponse.getOtherClaims().put(OAuth2Constants.ISSUED_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE);
        tokenResponse.getOtherClaims().put(ACCOUNT_LINK_URL, getLinkingUrl(uriInfo, authorizedClient, tokenUserSession));
        event.success();
        return Response.ok(tokenResponse).type(MediaType.APPLICATION_JSON_TYPE).build();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : VaultStringSecret(org.keycloak.vault.VaultStringSecret) FederatedIdentityModel(org.keycloak.models.FederatedIdentityModel) IOException(java.io.IOException) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 5 with VaultStringSecret

use of org.keycloak.vault.VaultStringSecret in project keycloak by keycloak.

the class AbstractOAuth2IdentityProvider method getSignatureContext.

protected SignatureSignerContext getSignatureContext() {
    if (getConfig().getClientAuthMethod().equals(OIDCLoginProtocol.CLIENT_SECRET_JWT)) {
        try (VaultStringSecret vaultStringSecret = session.vault().getStringSecret(getConfig().getClientSecret())) {
            KeyWrapper key = new KeyWrapper();
            String alg = getConfig().getClientAssertionSigningAlg() != null ? getConfig().getClientAssertionSigningAlg() : Algorithm.HS256;
            key.setAlgorithm(alg);
            byte[] decodedSecret = vaultStringSecret.get().orElse(getConfig().getClientSecret()).getBytes();
            SecretKey secret = new SecretKeySpec(decodedSecret, 0, decodedSecret.length, alg);
            key.setSecretKey(secret);
            return new MacSignatureSignerContext(key);
        }
    }
    String alg = getConfig().getClientAssertionSigningAlg() != null ? getConfig().getClientAssertionSigningAlg() : Algorithm.RS256;
    return new AsymmetricSignatureProvider(session, alg).signer();
}
Also used : KeyWrapper(org.keycloak.crypto.KeyWrapper) SecretKey(javax.crypto.SecretKey) VaultStringSecret(org.keycloak.vault.VaultStringSecret) SecretKeySpec(javax.crypto.spec.SecretKeySpec) AsymmetricSignatureProvider(org.keycloak.crypto.AsymmetricSignatureProvider) MacSignatureSignerContext(org.keycloak.crypto.MacSignatureSignerContext)

Aggregations

VaultStringSecret (org.keycloak.vault.VaultStringSecret)5 IOException (java.io.IOException)2 AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)2 SMTPMessage (com.sun.mail.smtp.SMTPMessage)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 URI (java.net.URI)1 KeyManagementException (java.security.KeyManagementException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 Date (java.util.Date)1 Properties (java.util.Properties)1 SecretKey (javax.crypto.SecretKey)1 SecretKeySpec (javax.crypto.spec.SecretKeySpec)1 MessagingException (javax.mail.MessagingException)1 Multipart (javax.mail.Multipart)1 Session (javax.mail.Session)1 Transport (javax.mail.Transport)1 AddressException (javax.mail.internet.AddressException)1 InternetAddress (javax.mail.internet.InternetAddress)1 MimeBodyPart (javax.mail.internet.MimeBodyPart)1 MimeMultipart (javax.mail.internet.MimeMultipart)1