How to configure or customize REALM Metadata endpoints in Keycloak for SAML2.0 - docker

Context:
I have a keycloak inside a docker, I understand that there is a "proxy reverse" doing something like transforming this url for example: "http://example.com" into "http://171.20.2.97:8082" (this is the actual place where the Keycloak is "deployed" or "up"). It is just an example, my clients when they need to consume an endpoint from one microservice of mine do not use numbers, they use example.com.
so in the Keycloak when you want to see the metadata of the realm for SAML2.0 you can do it by following this link which is in the REALM settings section:
https://example.com/auth/realms/REALM-NAME/protocol/saml/descriptor
as you can see I am using "example.com" not "171.20.2.97:8082" to access the metadata link.
The problem is that inside the METADATA, the endpoints for SingleSignOnService, SingleLogoutService, etc. Are all configured to be "http://171.20.2.97:8082/auth/realms/REALM-NAME/protocol/saml" (notice it is using the numbers and not example.com) and this causes that when the clients that want to use SAML.
Send inside their SAML REQUEST "Destination" attribute like so: "http://example.com/auth/realms/REALM-NAME/protocol/saml" and this causes an invalid request error, with reason invalid_destination, because the request attribute Destination was expected to be:
"http://171.20.2.97:8082/auth/realms/REALM-NAME/protocol/saml" like is inside the Metadata.
So my question is, how can I edit the metadata to change the endpoints numbers to example.com or if that is not possible, how can I make example.com get translated to 171.20.2.97:8082 inside my keycloak server? Or if you know another way to solve/figure out this it is very welcome

I feel like a BEAST after finding out how to achieve what I needed after like 3 weeks of searching about keycloak and SAML (I overcame many obstacles this was the lastone), finally I managed to fix this by using the "Frontend URL" setting in my REALM settings, there I can put anything I want so that it changes "http://171.20.2.97:8082/auth/" (inside the metadata urls) for whatever I configure there, so for example if I set Frontend URL to:
https://example.com/auth/
now all my metadata endpoints will be like so:
https://example.com/auth/realms/REALM-NAME/protocol/saml
instead of:
http://171.20.2.97:8082/auth/realms/REALM-NAME/protocol/saml
now my client is being able to properly login with SAML2 using keycloak.
how did I manage to find out this? Well there is not much info so this was what gave me the hint: Keycloak behind nginx reverse proxy: SAML Integration invalid_destination
The person asking said that he configured frontend-url, and I wanted to give a try to that, and after checking if that changed metadata urls, surprise it did =)

Related

[GSI_LOGGER]: The given origin is not allowed for the given client ID

I am trying to integrate the google-one-tap with my django project on my localhost.
So I added http://localhost:8000 and http://localhost into the Authorized JavaScript origins in Client ID for Web application.
I read some blogs that the above setting does work for the google-one-tap local testing, but it doesn't work for me.
Answer provided here worked for me: The given origin is not allowed for the given client ID (GSI)
As ridiculous as it seems omitting the port and writing http://localhost as JavaScript origin makes the new Google Identity Services code work.
Now my next question is how this change will affect the redirect url, which also accepted a port before.
I finally found out the solution.
It should be set the SECURE_REFERRER_POLICY in the settings.py like this.
SECURE_REFERRER_POLICY = "no-referrer-when-downgrade"
The setup is correct according to the setup instructions here.
Aside from following the above document, please also make sure you are sending the requests from the correct origin. In your case it should be from http://localhost:8000. Please also double check to see if the HTTP headers and parameters in the request also match the authorized origins.
Would you be able to find out which request failed from the web console?

ReactiveBase headers

I'm experimenting with ReactiveSearch and so far have tried the DataSearch and ResultList components. I'm looking over the required component to look at all the props and I see this
<ReactiveBase
app="appname"
credentials="abcdef123:abcdef12-ab12-ab12-ab12-abcdef123456"
headers={{
secret: 'reactivesearch-is-awesome'
}}
>
<Component1 .. />
<Component2 .. />
</ReactiveBase>
If the app is already secured using Appbaseio and the credentials gives my React app access to my ES cluster hosted there... what exactly could headers be used for? At first I thought username and password but you wouldn't do that.
What would be some of the scenarios where I SHOULD/COULD use the headers prop?
The headers are added to each request sent to the url. Normally you wouldn't need these. But in production you might want to add a layer of proxy server between your elasticsearch cluster and the client side ReactiveSearch code, this is where headers can be helpful.
You could add authentication in the flow. For example, you could restrict the elasticsearch calls to authenticated users by sending an access token via the headers prop and then verifying it at the proxy server (example of proxy server).
You could also implement some custom logic by adding custom headers and a logic to handle them at the proxy server.

Keycloak and Docker - Cannot set two types of URLs

I use standalone version of keycloak in docker-based application.
Since Keycloak 1.9.2 there is an "auth-server-url-for-backend-requests" attribute removed from keycloak properties.
This field was by me to indicate the internal ip address of auth server (inside a dock).
The external one (auth-server-url) is used for redirection purpose.
My question is: how to replace former auth-server-url-for-backend-request to solve a problem of having different network addresses inside docker and outside of it.
According to the following links, it appears you can use the same DNS for external requests as you would for internal. See these:
keycloak issue
http://keycloak.github.io/docs/userguide/keycloak-server/html_single/index.html#d4e4114
You should set the KEYCLOAK_FRONTEND_URL parameter in the Dockerfile or docker-compose.yml (if you use them). In other case your should set this parameter in Keycloak General settings UI.
Eg.:
It is quite tricky because you shouldn't set the real front-end's URL, however you should set the URL which is used by front-end. I have the same problem so you can see some examples in my SO question/answer

Stream remote file to client in ruby/rails 4/unicorn/nginx

I am trying to stream a file from a remote storage service (not s3 :-)) to the client using Ruby on Rails 4.2.
My server needs to stay in the middle of things to authenticate the client request but also to build up the request to the remote storage service since all requests to that service need to be authenticated using a custom header param. This makes it not possible to do a simple redirect_to and let the client download the file directly (but do let me know if this IS in fact possible using rails!). Also I want to keep the url of the file cloaked for the client.
Up until now I am using a gem called ZipLine but this also does not work as it still buffers the remote file before sending it to the client. As I am using unicorn/nginx, this might also be due to a setting in either of those two, that prevents proper streaming.
As per rails doc's instructions I have tried adding
listen 3000, tcp_nopush: false
to config/unicorn.rb but to no avail.
A solution might be to cache the remote file locally for a certain period and just serve that file. This would make some things easier but also creating new headaches like keeping the remote and cached files in sync, setting the right triggers for cache expiration, etc.
So to sum up:
1) How do I accomplish the scenario above?
2) If this is not a intelligent/efficient way of doing things, should I just cache a remote copy?
3) What are your experiences/recommendations in given scenario?
I have come across various solutions scattered around the interweb but none inspire a complete solution.
Thanks!
I am assuming you the third party storage service has an HTTP access. If you did consider using redirect_to, I assume the service also provides a means to allow per download authorization. Like unique key in the header that expires and does not expose your secret api keys or HMAC signed URL with expiration time as a param.
Anyhow, most cloud storage services provide this kind of file access. I would highly recommend let the service stream the file. Your app should simply authorize the user and redirect to the service. Rails allows you to add custom headers while redirecting. It is discussed in Rails guides.
10.2.1 Setting Custom Headers
If you want to set custom headers for a response then response.headers
is the place to do it. The headers attribute is a hash which maps
header names to their values, and Rails will set some of them
automatically. If you want to add or change a header, just assign it
to response.headers
So your action code would end up being something like this:
def download
# do_auth_check
response.headers["Your-API-Auth-Key"] = "SOME-RANDOM-STRING"
redirect_to url
end
Don't use up unnecessary server resources by streaming through them all those downloads. We are paying cloud services to that after all :)

rack-saml Assertion Consumer Service binding

I am using rack-saml as middleware with omniauth-shibboleth to allow my app to work as a Service Provider.
I would like to know how to set the binding for an Assertion Consumer Service (ACS) url?
Presently my ACS url binding is 'any'. However, I have searched in rack-saml and omniauth-shibboleth to find where this is being set, and have not been able to find it.
I am trying to get my app working with testshib.org in hopes of using the app with a similarly configured Identity Provider (IdP).
I have uploaded my metadata to testshib.org. I am not sure how to implement their custom shibboleth.xml file; however my app is able to redirect to their IdP login page and cookies are set by their IdP.
Hear are some errors from the testhib.org logs.
20:14:15.864 - WARN [org.opensaml.saml2.binding.AuthnResponseEndpointSelector:206] - Relying party 'https://test_shib.com' requested the response to be returned to endpoint with ACS URL 'https://test_shib.com:443/auth/shibboleth/callback' and binding 'any' however no endpoint, with that URL and using a supported binding, can be found in the relying party's metadata
20:14:15.864 - ERROR [edu.internet2.middleware.shibboleth.idp.profile.AbstractSAMLProfileHandler:447] - No return endpoint available for relying party https://test_shib.com
Any help would be greatly appreciated.
There may be a better way to do this; but I got things working by overriding Onelogin::Saml::Authrequest (and the other classes that called Onelogin::Saml::Authrequest) and then changing AssertionConsumerServiceURL to AssertionConsumerService in the create method.
in lib/rack/saml.rb you will find:
#config['assertion_consumer_service_uri'] ||= "#{saml_sp_prefix}#{#config['protected_path']}"
So, in your config/rack-saml.yml you can configure it like this (and you may need to if having the port number in the uri causes problems):
assertion_consumer_service_uri: https://www.abc.edu/users/auth/shibboleth/callback
Also, you shouldn't need anything from their shibboleth2.xml file, Just put the certificate from their provider's xml in your metadata.yml config file:
---
idp_lists:
https://idp.testshib.org/idp/shibboleth:
certificate: |-
-----BEGIN CERTIFICATE-----
MIIEDjCCAvagAwIBAgIBADANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzEV
...
8K/qhmFT2nIQi538n6rVYLeWj8Bbnl+ev0peYzxFyF5sQA==
-----END CERTIFICATE-----
saml2_http_redirect: https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO

Resources