Secure NodeJS APIs using keycloak
by Deepak Garg
Hi,
I have created a nodeJS rest api application. I want to secure my nodeJS
API layer using keycloak.
Please suggest me how I can achieve the same?
What configuration I need to do in the admin keycloak console? like under
client->access type should be public or bearer only?
Thanks,
Deepak
8 years, 5 months
Handling SuspectExceptions in Keycloak
by Sarp Kaya
Hello,
There is already an existing bug report for Infinispan here:
https://issues.jboss.org/browse/ISPN-6721
Currently for Keycloak, if this exception is thrown then it sends an Internal Server Error page to the browser. Essentially what would be really good is that it sends the user back to the login page instead of displaying Internal Server Error.
This happens when I am consistently sending login and logout (around 40 req/s) requests to two Keycloak instances (let’s call them kc1 and kc2), then one new keycloak instance is started kc3. Kc3 connects to kc1 and 2 in clustering mode.
Now kc1 receives a new request (such as login) and while it is processing that, kc3 is gracefully shut including the cache with this log:
2016-07-28 09:15:53,656 INFO [org.jboss.as.clustering.infinispan] (ServerService Thread Pool -- 61) WFLYCLINF0003: Stopped sessions cache from keycloak container
Just shortly after that (6 ms) kc1 throws an exception like this:
2016-07-28 09:15:53,662 ERROR [io.undertow.request] (default task-48) UT005023: Exception handling request to /auth/realms/{realm}/login-actions/authenticate: org.jboss.resteasy.spi.UnhandledException: org.infinispan.statetransfer.OutdatedTopologyException: Cache topology changed while the command was executing: expected 175, got 176
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:247)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:168)
at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:471)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:415)
then shortly after(150 ms) kc1 wants to talk to kc3 and fails to do so with this exception:
2016-07-28 09:15:53,804 ERROR [org.infinispan.interceptors.InvocationContextInterceptor] (default task-54) ISPN000136: Error executing command RemoveCommand, writing keys [f9bde276-dd03-41c9-995b-b1aaf64c1489]: org.infinispan.remoting.transport.jgroups.SuspectException: Cache not running on node kc3
at org.infinispan.remoting.transport.AbstractTransport.checkResponse(AbstractTransport.java:46)
at org.infinispan.remoting.transport.jgroups.JGroupsTransport.checkRsp(JGroupsTransport.java:763)
at org.infinispan.remoting.transport.jgroups.JGroupsTransport.lambda$invokeRemotelyAsync$73(JGroupsTransport.java:612)
at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:602)
at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
at org.infinispan.remoting.transport.jgroups.RspListFuture.futureDone(RspListFuture.java:31)
at org.jgroups.blocks.Request.checkCompletion(Request.java:169)
at org.jgroups.blocks.GroupRequest.viewChange(GroupRequest.java:261)
at org.jgroups.blocks.RequestCorrelator.receiveView(RequestCorrelator.java:331)
at org.jgroups.blocks.RequestCorrelator.receive(RequestCorrelator.java:242)
at org.jgroups.blocks.MessageDispatcher$ProtocolAdapter.up(MessageDispatcher.java:684)
at org.jgroups.JChannel.up(JChannel.java:738)
at org.jgroups.fork.ForkProtocolStack.up(ForkProtocolStack.java:123)
at org.jgroups.stack.Protocol.up(Protocol.java:374)
at org.jgroups.protocols.FORK.up(FORK.java:118)
at org.jgroups.protocols.FRAG2.up(FRAG2.java:165)
at org.jgroups.protocols.FlowControl.up(FlowControl.java:394)
at org.jgroups.protocols.ENCRYPT.up(ENCRYPT.java:454)
at org.jgroups.protocols.pbcast.GMS.installView(GMS.java:735)
at org.jgroups.protocols.pbcast.ParticipantGmsImpl.handleViewChange(ParticipantGmsImpl.java:140)
at org.jgroups.protocols.pbcast.GMS.up(GMS.java:922)
at org.jgroups.stack.Protocol.up(Protocol.java:412)
at org.jgroups.protocols.pbcast.STABLE.up(STABLE.java:294)
at org.jgroups.protocols.UNICAST3.up(UNICAST3.java:474)
at org.jgroups.protocols.pbcast.NAKACK2.deliverBatch(NAKACK2.java:982)
at org.jgroups.protocols.pbcast.NAKACK2.removeAndPassUp(NAKACK2.java:912)
at org.jgroups.protocols.pbcast.NAKACK2.handleMessage(NAKACK2.java:846)
at org.jgroups.protocols.pbcast.NAKACK2.up(NAKACK2.java:618)
at org.jgroups.protocols.VERIFY_SUSPECT.up(VERIFY_SUSPECT.java:155)
at org.jgroups.protocols.FD.up(FD.java:260)
at org.jgroups.protocols.FD_SOCK.up(FD_SOCK.java:310)
at org.jgroups.protocols.MERGE3.up(MERGE3.java:285)
at org.jgroups.protocols.Discovery.up(Discovery.java:295)
at org.jgroups.protocols.TP.passMessageUp(TP.java:1577)
at org.jgroups.protocols.TP$MyHandler.run(TP.java:1796)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
The key that it tries to write is the user-id. After this, the browser receives an Internal Server Error page, which looks like this in html:
<html>
<head>
<title>
Error
</title>
</head>
<body>
Internal Server Error
</body>
</html>
I have configured my infinispan cache settings as following (the rest are default):
<distributed-cache name="sessions" mode="SYNC" owners="5"/>
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
I have tried many things (such as playing with owner amounts or instance amounts etc). It does not seem to fix this exception. I am well aware that this seems more Infinispan issue than Keycloak, but I believe that Keycloak at least should respond the end user a better error message (perhaps a login again page) rather than an Internal Server Error page. Could you please handle this exception?
Kind Regards,
Sarp Kaya
8 years, 5 months
Creating a temporary landing page
by William Drescher [CELUM]
I have a use case that I'm attempting to accomplish with Keycloak but I'm not sure is possible/practical.
In our application we want to invite a user
This will cause the following steps to happen:
1. A User is created in Keycloak
2. An email is sent to the user with a unique address to confirm their registration
3. The registration page is created at that address
4. Either the landing page is removed (registration cancelled)/ user goes to registration and confirms their registration with additional information
Steps 1 and 2 are possible with existing functionality, was planning on creating a custom event and then using the event SPI to handle the event, creating the user and sending the email
I haven't been able to find a way to create a page reachable with an address. The Authentication provider documentation allows me to create a .ftl template which I can display to user through the context, but I was unable to find anything on displaying a page without an already existing user context. I would appreciate suggestions as to how to approach this, (or that it would be better to look at an implementation in the app itself instead)
Thanks,
Will
8 years, 5 months
Keycloak goes to AD to fetch users every page load, does not use local store.
by Ushanas Shastri
Classification: INTERNAL
Hello,
We have Keycloak setup with SQL Server as a persistent store, and we have User Federation enabled with Microsoft Active Directory.
Why does Keycloak go back to querying AD on every page load (Manage-> Users or the Evaluate tab in Authorization)? Should it not get a list of users from the local SQL store only?
I'm seeing that on the page load, Keycloak gets a list of all users from AD. Considering we have a large number of users, this is time consuming. Don't know if it matters, but we do have an AD filter.
Regards, Ushanas.
Viteos Fund Services Ltd | www.viteos.com<http://www.viteosfundservices.com/>
Direct : +91-22-61082230 | US : +1- 888-821-7561 extn 240
Cell : +91-9820225580
Email : ushanas.shastri(a)viteos.com<mailto:ushanas.shastri@viteos.com>
This message is for the named person's use only. It may contain confidential, proprietary or legally privileged information. No confidentiality or privilege is waived or lost by any mis-transmission. If you receive this message in error, please immediately delete it and all copies of it from your system, destroy any hard copies of it and notify the sender. You must not, directly or indirectly, use, disclose, distribute, print, or copy any part of this message if you are not the intended recipient. Viteos Capital Market Services Ltd.and any of its subsidiaries each reserve the right to monitor all e-mail communications through its networks. Any views expressed in this message are those of the individual sender, except where the message states otherwise and the sender is authorized to state them to be the views of any such entity
8 years, 5 months
External Source of Truth for Federated Identities (Social Auth)
by Josh Cain
Hi all,
I'm in a situation in which I need to consult an external source of truth
in order to pull social auth credentials (outside the Keycloak database).
I'd ideally like something functionally equivalent to the
UserFederationProvider, in which another source outside the user store is
consulted for this information. Is anything like that currently supported?
Josh Cain | Software Applications Engineer
*Identity and Access Management*
*Red Hat*
+1 843-737-1735
8 years, 5 months
Is failing to DB possible for Federated Users?
by Josh Cain
Hi all,
I'm using a Keycloak impementation in which the majority of our users come
from a UserFederationProvider. However, I'd ideally like to be able to
fall-back to the Keycloak database when this provider is unavailable. Is
it possible to do so?
I looked around at the codebase and UserFederationManager seems to be where
I'd like to change (namely the validateAndProxyUser
<https://github.com/keycloak/keycloak/blob/ec6b81e42dc8cb7abd9d06571a732cb...>
method). Is there any way to extend this with our own behavior? Looks
like that particular implementation is hard-coded into the KeycloakSession
interface.
Josh Cain | Software Applications Engineer
*Identity and Access Management*
*Red Hat*
+1 843-737-1735
8 years, 5 months
Naive Question
by Christopher Davies
I am looking at linking our legacy app to Keycloak.
Currently it is a bespoke jetty server, that only serves our war files.
The security.xml is set in config of the server directory.
I have taken the example setting file from
https://keycloak.gitbooks.io/securing-client-applications-guide/content/t...
I can see this loading keycloak's spring adapter.
It fails when searching for Keycloak.json.
I was hoping to be able to drop the Keycloak.json file in the config
directory.
Hope you can be of assistance. Please feel free to ask if I have missed any
key information.
I am trying to get up to speed on both KeyCloak and SpringSecurity as I am
a C++ programmer at heart.
Chris
8 years, 5 months
Re: [keycloak-user] Reverse Proxy - SSL Termination - Invalid parameter: redirect uri
by Derek Visch
Ended up figuring this out, just to save whatever poor soul has to go down
the same/similar path here's what I did. I'm curious why I didn't get any
errors when running keycloak with debug logging turned on as this must be
some kind of host re-write problem with wildfly/keycloak.
First the only configuration I had to set in standalone.xml was (I removed
all the other custom configurations I had in place the rest is the vanilla
standalone.xml )
<http-listener name="http-default" socket-binding="http"
redirect-socket="https" proxy-address-forwarding="true"/>
Wildfly10 Docs for this:
https://docs.jboss.org/author/display/WFLY10/Undertow+subsystem+configura...
Nginx configuration:
server {
listen 80;
server_name keycloak_testing.leveldatadevelopment.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name keycloak_testing.leveldatadevelopment.com;
ssl_certificate /etc/nginx/ssl/star.leveldatadevelopment.com.crt;
ssl_certificate_key /etc/nginx/ssl/star.leveldatadevelopment.com.key;
location / {
proxy_set_header *Host $host*;
proxy_set_header X-Real-IP $remote_addr; #*Not sure this is
needed for wildfly/keycloak*
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect http:// https://;
proxy_pass http://0.0.0.0:8080;
}
}
Note the Host different, with Host $host:$server_port; I receive a white
page when logging into the admin URL. *Why would this happen*? Only mention
of the host header I could find in the wildFly documentation is
https://docs.jboss.org/author/display/WFLY10/Undertow+subsystem+configura...
Also to get past the invalid_redirect_uri issue,
1. Run keycloak locally
2. Go to the Clients settings in the Master Realm
3. Click edit on the security-admin-console client id (You may also have
to do this with the account client ID I'm not certain)
4. Add valid redirect URI's for your new domain, for example
https://website.com/* (Docs tell you to be as limited as possible with
these so in production limit down your redirect URI's as much as possible)
Hope this helps someone in the future! What do you think? Should this be
added to the documentation somewhere or should some kind of error be thrown
in this circumstance? I'm not certain if it's Wildfly or keycloak causing
this to happen I didn't dig quite hard enough to find out :(
On Thu, Jul 21, 2016 at 5:21 PM, Derek Visch <derek.visch(a)gmail.com> wrote:
> Trying to setup reverse SSL for keycloak. Having issues finding
> documentation about this, it's mentioned in
> https://keycloak.gitbooks.io/server-installation-and-configuration/conten...
> but the extra detail that's supposed to be in
> https://keycloak.gitbooks.io/server-adminstration-guide/content/ I could
> not find in regards to reverse SSL proxys.
>
> Regardless I ended up following
> http://lists.jboss.org/pipermail/keycloak-user/2014-June/000453.html
>
> From that previous mailling list post:
>
> Follow the documentation for your web server to enable SSL and configure reverse proxy for Keycloak. It is important that you make sure the web server sets the X-Forwarded-For and X-Forwarded-Proto headers on the requests made to Keycloak. Next you need to enable proxy-address-forwarding on the Keycloak http connector. Assuming that your reverse proxy doesn't use port 8443 for SSL you also need to configure what port http traffic is redirected to. This is done by editing standalone/configuration/standalone.xml.
>
> First add proxy-address-forwarding and redirect-socket to the http-listener element:
>
> <subsystem xmlns="urn:jboss:domain:undertow:1.1">
> ...
> <http-listener name="default" socket-binding="http" proxy-address-forwarding="true" redirect-socket="proxy-https"/>
> ...
> </subsystem>
>
> Then add a new socket-binding element to the socket-binding-group element:
>
> <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
> ...
> <socket-binding name="proxy-https" port="443"/>
> ...
> </socket-binding-group>
>
>
>
> but now when I go to log on to the admin console I get "We're sorry ...
> Invalid aparameter: redirect uri".
>
>
>
> Tried stack overflow / google / IRC. No luck so far.
>
> Any help would be appreciated :D
>
> Thanks
>
>
>
--
*Derek Visch* / Software Developer / Network Technician
dvisch(a)leveldata.com <bipema(a)leveldata.com> / Direct: 269-488-2037
*Level Data Inc.*
Office: 866.511.3282
4787 Campus Dr. | Kalamazoo, MI 49008
http://www.leveldata.com
8 years, 5 months
NGINX + Redirect URI is going to http rather than https
by abhishek raghav
I am trying to configure NGINX as a reverse for my keycloak instance and
customer-portal to do SSL termination.
So I am accessing the customer-portal over NGINX with https which is going
fine.
The URL which i called looks like this:
https://192.168.99.100/customer-portal/
Next when I am trying to access any secured resourse by clicking on lets
say 'customer-listing', I am redirected to keyclock with the URI as below
with a error message as invalid redirect URI.
http://192.168.99.100:31048/auth/realms/nginx/protocol/openid-connect/aut...
Here if you see, the redirect URI is going as http in place of https. which
gives me invalid redirect-uri because the URI i have configured in
valid-redirect-URI section of settings in the customer-portal client
settings is below:
https://192.168.99.100/customer-portal/*
Am i missing something or i need to do anything else to support nginx
settings in my keycloak. I have made the proxy-forwarding in standalone.xml
also as 'true'.
<http-listener xmlns:ut="urn:jboss:domain:undertow:3.0"
*proxy-address-forwarding="true"*
name="default"
socket-binding="http"
redirect-socket="https"/>
port also I configured in the socket binding as 443.
Also i am configuring the required header in my nginx.conf.
Below is my nginx.conf looks like:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request"
'
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
server {
listen 443;
server_name "";
ssl_certificate /etc/nginx/external/cert.pem;
ssl on;
ssl_certificate_key /etc/nginx/external/key.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location /customer-portal/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $http_host;
proxy_set_header X-Forwarded-Port 443;
proxy_pass http://192.168.99.100:31050;
}
location /auth/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $http_host;
proxy_pass http://192.168.99.100:31048/auth/;
proxy_set_header X-Forwarded-Port 443;
}
}
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
And my keycloak.json file looks like below:
{
"realm": "nginx",
"realm-public-key":
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzb6ecdzvU+RoI0Qu6Psh1NFKLUoSuSfoAdW/nD5sr0M1FDpLOrsRIzIRScS9DJ28n1+Kdvrad9aS/UMsr+NXHRoSPeZuabAtfDCYx49+NhtR+LW97rB4lBNnXf148mkhikyZ0B08naQlhgkAqBXR5oxOo/FqWCObhZxBPsU9BcL4Qb5JO1we8k+7kIHTFyhHbZvEAk292eIG+GyrUDh+ZyE8T8Myde0GM1Korg9ZsdYxbb3U78bmxgvBmeye+Dq89EbyNDE3K/7giq7Gmh4Gu6fVcJG9tCjl1pS7CiDH1gTuITJxSJO3bPRf58SVoId8S26/5YMIq7pqwXe/pyvAewIDAQAB",
"auth-server-url": "https://192.168.99.100/auth/",
"ssl-required": "external",
"resource": "customer-portal",
"credentials": {
"secret": "20d8b6f8-25cc-481c-be66-133da68e9596"
},
"use-resource-role-mappings": false
}
Note: I am runnning all the 3 in there own docker containers.
Here my nginx url is *https://192.168.99.100 <https://192.168.99.100>*
my customer-portal url is *http://192.168.99.100:31050
<http://192.168.99.100:31050>*
my keycloak server url is *http://192.168.99.100:31048
<http://192.168.99.100:31048>*
Customer-portal is running on tomcat 8 with keycloak tomcat adapter.
customer-portal and keycloak, both are running behind nginx.
Am i doing something wrong.
Thanks.
Abhishek
8 years, 5 months