Reputation:
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
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
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
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