Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keycloak Identity Broker API

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();

    }
like image 498
yormen Avatar asked Jun 26 '19 15:06

yormen


People also ask

What is identity brokering in Keycloak?

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.

Does Keycloak have an API?

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.

Is Keycloak an identity provider?

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.


1 Answers

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.

like image 163
Vadim Ashikhman Avatar answered Oct 23 '22 11:10

Vadim Ashikhman