user6033462
user6033462

Reputation:

How to set redirect_uri in Keycloak with Spring boot

I am using Keycloak in my Spring Boot application, but I cannot figure out, how to provide my own redirect uri

This is my configuration

keycloak:
    use-resource-role-mappings: true
    realm: customer-realm
    resource: web-frontend
    token-minimum-time-to-live: 30
    principal-attribute: preferred_username
    credentials:
        secret: 321321321-88a2-424c-bb4c-2312312321
    auth-server-url: http://auth.customer.mydomain.tld:9080/auth

I have tried to set the redirect_uri in the following way

   <a href="/login?redirect_uri=http://localhost:8443/customer/account">Login</a>

Of course I have added this URI into my realm settings.

But when a user clicks on the link it looks as follows

http://auth.customer.mydomain.tld:9080/auth/realms/customer-realm/protocol/openid-connect/auth?response_type=code&client_id=web-frontend&redirect_uri=http%3A%2F%2Flocalhost%3A8443%2Fsso%2Flogin&state=e81ad405-8a83-4e84-a155-2f1275f4390b&login=true&scope=openid

How can I provide my own redirect URI ?

Thanks

Upvotes: 6

Views: 12979

Answers (3)

Bob Lauer
Bob Lauer

Reputation: 31

The question's title is a bit misleading, you do not set a redirect_uri in Keycloak, you set it in Spring Boot so that it will redirect to Keycloak with this redirect_uri as a parameter.

Anyway, after experimenting a bit in a setup with Spring Boot/keycloak/reverse proxy I discovered that the Spring Boot property

spring.security.oauth2.client.registration.keycloak.redirect-uri=http://somehost/login/oauth2/code/keycloak

is responsible for setting the redirect_uri param in the keycloak URL that Spring redirects to. There also seems to be some check in Spring when keycloak redirects back after a successful login.

So the variable is actually a re-redirect URI if you will.

Upvotes: 3

Julian
Julian

Reputation: 401

I don't know if the question is still relevant but I stumbled upon the same issue. And although there is the possibility to rewrite parts of the URI via the configuration keycloak.redirect-rewrite-rules.pathOld=pathNew this does not apply for the authority, i.e. the domain-name. But the domain name for the redirect-uri is taken from the Host header of the request, thus it is sufficient to set this header appropriately e.g. in a proxy.

Alternatively you would need to inject a custom PostProcessor which finally injects a subclassed OAuthRequestAuthenticator with overwritten getRequestUrl(). A sketched Code would look something like that:

@Component
public class KeycloackAuthenticationProcessingFilterPostProcessor implements BeanPostProcessor {

    private static final Logger logger = LoggerFactory.getLogger(KeycloackAuthenticationProcessingFilterPostProcessor.class);

    private void process(KeycloakAuthenticationProcessingFilter filter) {
        filter.setRequestAuthenticatorFactory(new SpringSecurityRequestAuthenticatorFactory() {
            @Override
            public RequestAuthenticator createRequestAuthenticator(HttpFacade facade, HttpServletRequest request, KeycloakDeployment deployment, AdapterTokenStore tokenStore, int sslRedirectPort) {
                return new SpringSecurityRequestAuthenticator(facade, request, deployment, tokenStore, sslRedirectPort) {

                    @Override
                    protected OAuthRequestAuthenticator createOAuthAuthenticator() {
                        return new OAuthRequestAuthenticator(this, facade, deployment, sslRedirectPort, tokenStore) {

                            @Override
                            protected String getRequestUrl() {
                                return "http://localhost:8080";
                            }
                        };
                    }

                };
            }
        });
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof KeycloakAuthenticationProcessingFilter) {
            logger.info("Injecting Custom handler...");
            process(((KeycloakAuthenticationProcessingFilter) bean));
        }
        return bean;
    }
}

As I have a proxy in place I took the easy path and just adjusted the Host header accordingly.

Upvotes: 4

Kosi2801
Kosi2801

Reputation: 23115

We have a spring boot application which sets this through the configuration:

@Configuration
public class Config {
    @Value("${app.client.id}")
    private String clientId;

    @Value("${app.client.secret}")
    private String clientSecret;

    @Value("${auth.server.hostname}")
    private String authServerHost;

    @Value("${auth.server.port}")
    private String authServerPort;

    @Bean
    public SecurityConfiguration securityInfo() {
        Map<String, Object> additionalQueryStringParams = new HashMap<>();
        additionalQueryStringParams.put("redirect_uri", 
          "http://" + authServerHost + ":" + authServerPort + "/sso/login");
        return new SecurityConfiguration(clientId, clientSecret, "", "", "", additionalQueryStringParams, false);
    }
}

Maybe this also works for you?

Upvotes: 2

Related Questions