So i have a client which consumes an api. The API is secured with keycloak. Users signs in normally, but i want to allow users to sign in user without having to go keycloak's login page with their social media accounts like facebook or google. I need a rest API with an implementation of how to get a url generated so when user click on this url in a button, it will take the user to the respective social login page to login while keycloak still serves as the broker.
Below is my implementation, it generates a url alright but does not take the user to google page to login
This is a rest Controller
@Secured("permitAll")
@GetMapping(path = "/generator")
public String brokerGenerator(HttpServletRequest httpServletRequest) throws ServletException {
String provider = "google";
String authServerRootUrl = "http://localhost:8080/";
String realm = "realmName";
String clientId = "clientName";
String nonce = UUID.randomUUID().toString();
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
String input = nonce + clientId + provider;
byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
String hash = Base64Url.encode(check);
httpServletRequest.getSession().setAttribute("hash", hash);
String redirectUri = "http://localhost:4200/dashboard";
return KeycloakUriBuilder.fromUri(authServerRootUrl)
.path("auth/realms/realmName/google/link")
.queryParam("nonce", nonce)
.queryParam("hash", hash)
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri).build(realm, provider).toString();
}
As an intermediary service, the identity broker is responsible for creating a trust relationship with an external identity provider in order to use its identities to access internal services exposed by service providers.
Keycloak connection using a Java application This application connects to your Keycloak instances and uses Keycloak's authentication and authorization capability through its REST API.
An identity provider (IDP) is a service that can authenticate a user. Keycloak is an IDP. Keycloak can be configured to delegate authentication to one or more IDPs. Social login via Facebook or Google+ is an example of identity provider federation.
Keycloak supports this out of the box. See https://www.keycloak.org/docs/latest/server_admin/index.html#_client_suggested_idp
OIDC applications can bypass the Keycloak login page by specifying a hint on which identity provider they want to use.
This is done by setting the kc_idp_hint query parameter in the Authorization Code Flow authorization endpoint.
UPDATE
In your case you should use normal Keycloak Auth Code Flow endpoint and in addition to the basic query params provide kc_idp_hint
param. This way the user is redirected to Keycloak login page first then Keycloak redirects him to the chosen identity provider login page (google in your case).
Here is an example redirect URL:
https://keycloak-domain/realms/REALM_NAME/protocol/openid-connect/auth?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE&response_type=code&scope=openid&nonce=NONCE&kc_idp_hint=google
Edit your code according this example:
return KeycloakUriBuilder.fromUri(authServerRootUrl)
.path("realms/realmName/protocol/openid-connect/auth") // Url changed
.queryParam("response_type", "code") // Autherization Code Flow
.queryParam("scope", "openid") // Add additional scopes if needed
.queryParam("kc_idp_hint", "google") // This should match IDP name registered in Keycloak
.queryParam("nonce", nonce)
.queryParam("hash", hash)
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri).build(realm, provider).toString();
You can manually initiate Keycloak redirection for test. Start normal login flow and when you redirected to Keycloak login page do not enter credentials, instead add kc_idp_hint=google
to the URL and hit ENTER. Then you will be redirected right to Google login page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With