Stand up a keycloak instance w/ username: admin, password: pa55word. With postgres as a database. And SSL forwarding (for use with like cloudflare).
Create this docker-compose file i.e. docker-compose.yml
version: '3'
volumes:
postgres_data:
driver: local
services:
postgres:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: quay.io/keycloak/keycloak:latest
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: Pa55w0rd
PROXY_ADDRESS_FORWARDING: 'true'
# Uncomment the line below if you want to specify JDBC parameters. The parameter below is just an example, and it shouldn't be used in production without knowledge. It is highly recommended that you read the PostgreSQL JDBC driver documentation in order to use it.
#JDBC_PARAMS: "ssl=true"
ports:
- 8010:8080
depends_on:
- postgres
Then run docker-compose up -d
.
With that in place, you just need to
- Make a new realm
- Make a new client
- Add a valid redirect uri to the client (from the application you are wishing to secure)
Then you can add the following type of logic for authentication on your browser facing application
var keycloak;
function init() {
keycloak = new Keycloak({
url: 'https://[key-cloak-instance]/auth',
realm: '[your-realm]',
clientId: '[your-client]'
});
keycloak.init({
checkLoginIframe: false
}).success(async function (auth) {
if (auth) {
var name;
if (keycloak.tokenParsed['family_name'] || keycloak.tokenParsed['given_name']) {
name = keycloak.tokenParsed['given_name'] + ' ' + keycloak.tokenParsed['family_name']
} else {
name = keycloak.tokenParsed.preferred_username;
}
hide('login')
// Set axios header for auth
axios.defaults.headers.common['Authorization'] = `Bearer ${keycloak.token}`;
} else {
console.info('Not Authenticated');
window.location = await keycloak.login();
}
})
}
function show(id) {
document.getElementById(id).classList.remove('hide');
document.getElementById(id).classList.add('show');
}
function hide(id) {
document.getElementById(id).classList.add('hide');
document.getElementById(id).classList.remove('show');
}
window.onhashchange = init;
window.onload = init;
Then on your server (nodejs/express in this case), add the following logic:
const jwt = require('express-jwt');
const { data: response } = await axios.get('https://[keycloak-instance]/auth/realms/[your-realm]');
const secret = `-----BEGIN PUBLIC KEY-----\r\n${response.public_key}\r\n-----END PUBLIC KEY-----`;
const jwtMiddleware = jwt({ secret, algorithms: ['RS256'] });
And then you can either add the middleware globally
app.use(jwtMiddleware)
Or add it to a specific route
app.post('/api/endpoint', jwtMiddleware, async (req, res) => {
return 'something-secure';
});
Now good luck to those pesky people that were previously trying to storm your castle!
Top comments (1)
thank you, this is very good start for me to spin-up my Keycloak server on my domain using Docker plus Nginx reverse proxy. Though I modify a lot :)