I have a keycloak client sample-application. It has valid-redirect-uri https://sample-application.mycompany, a frontend service. This frontend calls backend service, sending JWT token in http header. Backend service checks allowed-origins in this JWT token. https://sample-application.mycompany is there, so everything works fine in production.
"allowed-origins": [
"https://sample-application.mycompany"
]
Now we are doing some e2e tests, and we are calling this backend, but from a different place - http://jenkins.mycompany. We have a proper JWT token, but backend service fails on allowed-origins validation, because http://jenkins.mycompany is not there.
My options:
add additional valid-redirect-uri http://jenkins.mycompany to my client - I don't want to do that, adding testing stuff to production clients seems bad
make copy of a client sample-application-testing, with additional valid-redirect-uri, use it for tests, delete afterwards
tried using server's private-key to generate my own JWT with extra entry in allowed-origins, but it failed later, because server validates this token
tried some magic with setting different Origin headers, but it seems impossible, browser protection I guess
Is there any other possibility?
Edit - the validation I'm talking about, checks if Origin header is in allowed-origins list. To be clear: this is not something I invented myself. This validation comes from keycloak-spring-boot-starter, here is the relevant fragment: https://github.com/keycloak/keycloak/blob/17117820cc14f87f5990ddce80ef38a0e2e7f314/adapters/oidc/adapter-core/src/main/java/org/keycloak/adapters/AuthenticatedActionsHandler.java#L126
Keycloak allows one to add multiple multiple Valid Redirect URIs as well as multiple Web Origins. One of these should allow you to add the URL for your test server and have it appear in the Allowed Origins in the JWT.
More commonly, test environments will have their own copy of production servers so as not to interfere with production operations. This is pretty standard. For a CI/CD setup, it makes more sense to use some kind of a stub or mock validator (something that can be spun up locally) to avoid setting up a server entirely
Below is a screenshot of the settings in the Client configuration in Keycloak 19
Related
I am using Angular 5 to send post request to send SMS through Bulksms : http://bulksms.com/
When making the request from Angular (client), I am facing this issue :
Origin http://TTTT:4200 is not allowed by Access-Control-Allow-Origin.
How can I correct this issue in BulkSMS ?
Regards,
Your browser's same-origin policy is restricting your Javascript code from accessing a third party (i.e. api.bulksms.com in this case) in the way in which you hoped to do it - and CORS (Cross-Origin Resource Sharing), which is a mechanism to relax those restrictions, is not relaxed enough to allow these requests (from you as an untrusted third party) either.
Wikipedia Same-origin policy : "Under the [same-origin] policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page". The Wikipedia page contains some good examples of the sorts of malicious Javascript code uses that the same-origin policy tries to limit.
It is important to note that these restrictions are only enforced by browsers: HTTP client code that is not running under a browser typically doesn't care about any of this.
For development purposes, there are some tools that can make your life easier - for example, you could use live-server to run a simple HTTP server which serves up your static files, while also using its --proxy option to route requests to api.bulksms.com and solve your same-origin policy problem in the process.
For production, a typical solution is to route your AJAX requests, which are destined for the third party service, via your own server (the one serving up your Javascript files to your browser), or a reverse proxy (which would front both your own and the third party service). If there is a server side to your application, you can make the HTTP requests to api.bulksms.com from there, using an HTTP client, and then have your Javascript code talk to your own server, to indirectly make the requests to bulksms.com. This also gives you the opportunity to add authentication headers on your server side, without your Javascript code ever having to know them (e.g. if you have one bulksms.com account, and many users able to use that account via your Angular app, but who should not know your credentials). Similarly, you could impose limits on what your Angular users can do in this way (e.g. to limit the number of SMSs they could each send per day).
On user auth success my auth server generates a token and passes it to the client.
The docs say that the client has to add the following headers:
X-Auth-CouchDB-UserName: username;
X-Auth-CouchDB-Roles:comma-separated (,) list of user roles;
X-Auth-CouchDB-Token: authentication token.
Does it mean that the client defines his own roles on every request? Why can't he add 'admin' into the list of roles then?
A client is anything that uses or requests resources from a server.
"The client" in this case is your proxy/auth server, not a web browser. (The documentation could probably stand to be clarified a bit.)
So yes, your proxy/auth server, the client to CouchDB, should set that header as appropriate.
By extension, it should also not pass through any X-Auth-Couch headers received from its client (presumably a web browser).
Good observation. Using the JWT Authentication would seem to close this loophole as my understanding is the entire token is signed-over.
That said, in neither case can one avoid:
having to fully trust the entity holding the secret
having to carefully guard against leakage of its headers
The former is sort of unavoidable, as the point of these plugins is to delegate authentication. Either you trust the proxy (or JWT issuer) or you leave those authentication_handlers disabled.
The latter is something that e.g. OAuth 1 hardened itself somewhat against, in that ± the entire request was signed over and one couldn't simply take a couple auth headers from an earlier leaked request and slap them on a new forged request. Nonce and timestamp fields were supposed to be checked to avoid verbatim replays of prior requests as well. (All this was dropped in OAuth 2 for whatever that's worth… and even OAuth 1 had some notable loopholes in practice…)
So in practice either the Proxy or the JWT authentication handlers should be used with care. Assuming a "firewall" of sorts drawn around both your CouchDB and authentication source, then as #Flimzy's answer mentions preventing unexpected headers making their way inwards from outside that boundary — as well as keeping the real headers from leaking outwards — should mitigate most potential abuse.
I see most examples using it with form-based authentication (i.e. we load the mod_auth_form.so and other session modules). Is it possible to use this session timeout along with basic authentication (i.e. we load mod_auth_basic.so ) ?
Also, I know that the mod_session was introduced only after apache2.3, so this would definitely not be supported in apache2.2 I am fine even if it works just for apache 2.4.
It's not implemented in any other auth modules, but it's also unnecessary. Most other auth modules use HTTP basic auth, where the credentials are seamlessly transmitted on every subsequent request to the same host+context root.
But mod_auth_form needs to do a one-time capture/prompt/validate that cannot be propagated on every request. Hence the need to put them in a session store.
I was reading articles about token based authentication.
And when I was going through this article "Cookies Vs Tokens", I did not understand the following four points (I have asked my doubts below each of the quoted points)
Cross-domain / CORS: cookies + CORS don't play well across different
domains. A token-based approach allows you to make AJAX calls to any
server, on any domain because you use an HTTP header to transmit the
user information.
Why now there will not be cors problem ? What if someone one from the neighboring tab in the browser steals your token(because in javascript of that domain there is code which can clearly tell where the token is stored and how it is retrieved) and starts making
requests ?
And more over it is said "cookies + cors" . why is it said that cookie and cors don't play well ?
CDN: you can serve all the assets of your app from a CDN (e.g.
javascript, HTML, images, etc.), and your server side is just the API.
Why is this an advantage in token based auth systems ? We were using cdn's even when we were doing cookie based authentication right ?
This was because script tags can call scripts from other domains any way right ?
CSRF: since you are not relying on cookies, you don't need to protect
against cross site requests (e.g. it would not be possible to
your site, generate a POST request and re-use the existing
authentication cookie because there will be none).
What if someone one from the neighboring tab in the browser(from some other domain) steals your token and starts making
requests ? I cannot understand this either.
Mobile ready: when you start working on a native platform (iOS,
Android, Windows 8, etc.) cookies are not ideal when consuming a
secure API (you have to deal with cookie containers). Adopting a
token-based approach simplifies this a lot.
Did not understand it completely . Can someone explain , how?
The linked article is a bit sloppily written and does not properly define and distinguish between the various concepts.
First, you have to define what exactly you mean by "token based". The article does not do that, but it seems it has OAuth 2.0 JWT access tokens with the Bearer Token Usage (http://self-issued.info/docs/draft-ietf-oauth-v2-bearer.html) in mind. This means that:
Bearer access tokens are used. The upside of bearer tokens (as opposed to MAC token usage) is simplicity of usage -- all a client needs to pass to a server is a token. The downside is that whoever gets hold of such a token is considered its rightful owner, so he can do whatever he wants with it.
Tokens are passed in the Authorization HTTP header, following a specific syntax.
Then you have to define what you really mean by "cookie based" authentication -- which again, the article does not do. A cookie, essentially, is just a transport mechanism to pass data back and forth between client and servers of a specific domain, without the client having to do anything explicitly. So you can really stuff pretty much anything into a cookie -- even OAuth 2 access tokens.
What the author seems to have in mind is server side-managed sessions where a session id is passed in a cookie.
With these definitions in mind, it is possible to answer your questions:
Cross-domain / CORS: cookies + CORS don't play well across different domains. A token-based approach allows you to make AJAX calls to any server, on any domain because you use an HTTP header to transmit the user information.
This is true, but for different reasons: Cookies are scoped to a specific domain, so as long as you use cookies to pass a session id between clients and servers, you are bound to having to put all servers under one domain. This looks like a limitation, but the true limitation is somewhere else -- when using server side-managed sessions, a session id will only make sense to those servers who have access to the server side session management. Any server outside the domain most likely cannot make any sense of a session id.
A JWT access token, however, is self contained and can be interpreted by other parties as well. This is why access tokens are well suited for cross-domain/cross-service calls.
CDN: you can serve all the assets of your app from a CDN (e.g. javascript, HTML, images, etc.), and your server side is just the API.
Yes. But this does not really matter in practice because anyting you put into a CDN will most likely not require authentication in the first place -- so this is kind of a silly argument.
CSRF: since you are not relying on cookies, you don't need to protect against cross site requests (e.g. it would not be possible to your site, generate a POST request and re-use the existing authentication cookie because there will be none).
The danger of cookies w.r.t. CSRF is that they are passed implicitly to the server -- the browser adds a cookie to the request, regardless of whether it was good of rogue code that triggered the request.
When tokens are passed in a cookie, this danger applies to tokens we well. However, when they are passed in a header (as the Bearer Token Usage spec defines), this danger does not exist as the header needs to be added to teh request explicitly, every single time. This makes this approach more CSRF-safe than cookies.
However, when the rogue code can get hold of the token some other way (because it was passed as a URL parameter, for example (which the spec allows), it is still possible to make CSRF attacks with tokens.
Mobile ready: when you start working on a native platform (iOS, Android, Windows 8, etc.) cookies are not ideal when consuming a secure API (you have to deal with cookie containers). Adopting a token-based approach simplifies this a lot.
Dealing with cookie containers is usually easier than setting up OAuth, so I do not buy into this one.
Alright, I'll try to go through these in as structured a way as possible:
CORS + Cookies: Cookies were never meant to travel across domains. A cookie must be submitted to the server from its origin, cross-origin cookies don't exist. There is no need to worry about another application accessing the token if it's stored in localstorage since that one is site-specific, e.g every site gets it own allotted space of localstorage.
I'm not certain about this one. I'd assume they mean an authenticated CDN, e.g you provide a token to get access to the resources
Again, the token won't be stolen by a neighbour, because of how localstorage works. If you're worried you could actually issue a new token from the server with every response, effectively making one-time use tokens. That way, even if your token is compromised, it is far less likely to work.
Cookies are fairly complex structures, and if you one day decide you want to consume your API on a mobile device, it will be much easier to use a token, which is just a string (compared to a structured object)
The most important difference is that tokens are stateless, while cookies are not. Cookies will contain information about the authenticated user and context-specific data. A token, on the other hand, is just a string that an API consumer assumes can be used to access restricted data.
I've setup security in my RESTFUL WCF services using Custom Basic Authentification (thus desactivating the iis Basic Authentification and not using Windows Accounts Login at all; my service is hosted by iis) using the following link.
blog link
I understand the consumers have to implement a client to pass credentials in the request header.
It is 64bits based encoded and we can see credentials passing in firebug network tab while debugging (it is always the same string encoded <=> same credential .......)
So, in addition, to enforce security I will add SSL to encrypt the url :
https://myrestfulserviceurl.com/Method
Now the consumers ask me why we don't just put the login and password in the url request i.e
https: // myrestfulserviceurl.com/Method?login=XXX&password=YYY
(also combined with SSL)
Thus the change requires to add login and password as parameters in my Operation Contract and call a method for authentification in my method "Method".. etc etc
My question is :
What is the difference (both scenarii will use ssl) between Custom Basic Authentification (credentials in request header) & simply passing credentials in url in param ?
I mean : I'm just asking myself why I do bother to implement Basic Authentification. Passing credentials in url or in header look similar : it's passing stuff in the request. But talking in term of security, it looks the same ?
Basic Authentification looks not more secure excepted the 64bits based encoding.
Correct me if i'm wrong.
I am just looking a reason why implementing Custom Basic Authentification.
Any idea/advise?
Thanks
The main difference that comes to mind is to do with how visible the data is and how long it is likely to be retained.
For instance, assuming SSL is terminated at your application server, values in the get parameters are likely to be automatically logged to your file system (in request logs for instance). Having usernames and passwords in there is not ideal as it makes it much easier for them to be leaked.
If SSL is terminated at a loadbalancer or some similar proxy, then the usernames and passwords could be saved in request logs on servers you may not be thinking about and probably have less control over.
By contrast, the Authentication header is much less likely to be logged to places you're not expecting.
I thought about doind this myself and decided against it because i wanted the Restful URL's to focus only on the operations and keep security out of it, for example I might want to re-use the same code on a different application.
Also Im not sure but i think there could be a security implication concerning replay attacks, if someone obtained the link then they could execute it in any http client. If you used the authroisation attribute in the http header you could avoid this by putting an expiration on it. Also i think its better to hide this information from the html page body.
The dude who wrote this http://lbadri.wordpress.com/2012/07/30/anatomy-of-a-simple-web-token-swt/, which is taken from his book "Pro ASP.NET web Security". Gives a pretty decent example of creating a token which you could then use in the http header "Authorisation", like: Authorization: Basic d2FsaWRAGssSGZ21haWwuY29tOn236dhbGlk