First of all this section(8.3. Setting Up a Load Balancer or Proxy) of Keycloak documentation was absolutely helpful. I was able to make things somehow working but I still feel things can get done better and in more secure way!
I am not going to repeat needed configuration for Keycloak side, but I rather provide some hints for you in case you are using Nginx as reverse proxy.
Here is my nginx.conf
which includes required configs:
```
upstream rock-app {
server rock-app:8080;
}
upstream keycloak {
server keycloak:9080;
}
server {
listen 80;
listen 443 ssl http2;
...
add_header Strict-Transport-Security "max-age=86400; includeSubdomains; preload" always;
...
}
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://rock-app;
}
location /auth {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://keycloak;
}
```
Note: add_header Strict-Transport-Security ...
part is important and ensure us users will stay in https protocol when they enter the site with a https url. please correct me if I am wrong!?
Now If I visit following url:
https://my-example.com/auth/realms/jhipster/.well-known/openid-configuration
I will see this response:
{
"issuer": "http://my-example.com/auth/realms/jhipster",
"authorization_endpoint": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/auth",
"token_endpoint": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/token",
"token_introspection_endpoint": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/token/introspect",
"userinfo_endpoint": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/userinfo",
"end_session_endpoint": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/logout",
"jwks_uri": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/certs",
"check_session_iframe": "http://my-example.com/auth/realms/jhipster/protocol/openid-connect/login-status-iframe.html",
"grant_types_supported": ["authorization_code", "implicit", "refresh_token", "password", "client_credentials"],
"response_types_supported": ["code", "none", "id_token", "token", "id_token token", "code id_token", "code token", "code id_token token"],
"subject_types_supported": ["public", "pairwise"],
"id_token_signing_alg_values_supported": ["RS256"],
"userinfo_signing_alg_values_supported": ["RS256"],
"request_object_signing_alg_values_supported": ["none", "RS256"],
"response_modes_supported": ["query", "fragment", "form_post"],
"registration_endpoint": "http://my-example.com/auth/realms/jhipster/clients-registrations/openid-connect",
"token_endpoint_auth_methods_supported": ["private_key_jwt", "client_secret_basic", "client_secret_post"],
"token_endpoint_auth_signing_alg_values_supported": ["RS256"],
"claims_supported": ["sub", "iss", "auth_time", "name", "given_name", "family_name", "preferred_username", "email"],
"claim_types_supported": ["normal"],
"claims_parameter_supported": false,
"scopes_supported": ["openid", "offline_access"],
"request_parameter_supported": true,
"request_uri_parameter_supported": true
}
As you may notice http://my-example.com/...
is shown instead of https://my-example.com/...
Therefore I had to change following config of my realm(jhipster-realm.json) from
"sslRequired" : "external",
to
"sslRequired" : "none",
which I don't know if is a bad thing? considering (1) my browser never leaves https when I do test login workflow and (2) my keycloak instance is not accessible through any public port.
Well I am not going to accept my own answer as accepted answer, because as I said earlier I feel things can get done better and in more secure way. Thanks!
Update
I've done following changes for using https protocol:
Dockerfile
FROM jboss/keycloak:3.4.1.Final
standalone.xml
<server name="default-server">
...
<http-listener name="default" socket-binding="http" redirect-socket="proxy-https" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING}" certificate-forwarding="true" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" proxy-address-forwarding="${env.PROXY_ADDRESS_FORWARDING}" certificate-forwarding="true" enable-http2="true"/>
...
<socket-binding-group ...
<socket-binding name="proxy-https" port="443"/>
...
nginx.conf
upstream keycloak {
server keycloak:9443;
}
...
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
...
location /auth {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass https://keycloak;
}
...
jhipster-realm.json
...
"sslRequired": "external",
HTH, Thanks!