Keycloak add extra claims from database / external source - jwt

I have not been able to divine the way I might add extra claims from my application database. Given my limited understanding, I see two ways:
After successful authentication have keycloak pull extra claims from the application database somehow. This app database is postgres, for example.
Have the application update the jwt with extra claims using a shared key.
I would like some feedback both paths. I feel that the fist option may be safer. However I am not sure where to begin that implementation journey.

Answering my own question here. I cross-posted this question to the Keycloak users mailing list here (http://lists.jboss.org/pipermail/keycloak-user/2017-April/010315.html) and got an answer that seems reasonable.
This is pasted from the answer I received there.
I use the first option. I do it with a protocol mapper, which is a convenient place to do it because there the token is already built by keycloak but hasn't been signed yet. This is the procedure :
User logs in
My custom protocol mapper gets called, where I overwrite the transformAccessToken method
Here I log in the client where the protocol mapper is in into keycloak, as a service. Here don't forget to use another client ID instead the one you're building the protocol mapper for, you'll enter an endless recursion otherwise.
I get the access token into the protocol mapper and I call the rest endpoint of my application to grab the extra claims, which is secured
Get the info returned by the endpoint and add it as extra claims

Related

Extend user access token in Keycloak with external data

We use the Keycloak service as SSO solution and provide the resulting JWT to different microservices and that works very well.
But now we have the problem that the JWT must be extended with data from an external resource when the user tries to login.
More tangible, a user has access to different markets with an unique ID as identifier, but we didn't see the management which user have access to which market inside the Keycloak service.
What could be the best solution for this problem?
After reading the docs an custom User Storage SPI is an answer, but I think that is a little bit to much..
As information we use Keycloak 3.1.0 as a standalone service with an postgres DB
The way you add extra data/information to your keycloak JWT token payloads, comes by means of adding "client-scopes" configured with the proper protocol mappers within them, that allows you to add any amount of custom extra information to your Id-token and access-token.
One example of this, would be having extra variables in your users, and then in the protocol mappers within the (newly-created) "client-scope", you can add a protocol-mappers of type "User-Attribute", so that your specific user variable will appear in your token the way you configured on your "protocol-mapper". There are many types of "protocol mappers" that'll allow you to map diverse type information to your tokens (is not just for mapping user variables).
This was addressed on this question before:
Keycloak User Storage SPI Implementation
I'm copying here the part which is relevant to you:
Origianl question was:
[How to]"Retrieve some attributes from external datasource, map it to keycloak's id and access token. Need to retrieve users unique id and add it as subject id in the jwt. That's the id, rest of the services can use to retrieve the id, when this token is passed to other services."
[Answer:]
For this, the best you can do is:
Add those user's unique data as users attributes (see them on the Admin console)
Create a "Client scope" on Keycloak, with a corresponding mapper of type "user property" to map each of those values you'd like to add (from your user data) to your Id-token and access-token. You also need to tie your client with your just created "client scope". This may sound a little bit confusing, but this video is great material and I bilieve it'll help you alot: https://www.youtube.com/watch?v=ZxpY_zZ52kU (arround min 6:30 you'll see how to add extra user info to your tokens)

Resource-Server for IdentityServer 4

My task is to implement a resource server(RS) for IdentityServer4(IS4). The RS should fetch data from a database and send the necessary information as a json object back to the caller (client). This is needed because we have to return complex objects.
I already setup IS4 succesfully and its already running in Docker for testing purpose. I also setup the needed database.
My understanding of the flow would be, the user requests data from the RS sending the access-token, the RS then validates the token, checking if the caller is allowed to access the api using the IS4, if everything is okay the RS returns the data to the caller.
My problem is, as I'm new to this subject, how would I implement a RS? Do I create an API which is added as a scope to the user? Or is there a RS already implemented in IS4?
So yes you'll need to write your own API to serve your own resources, IdentityServer will only manage your identities for you (as well as handling external logins if that's what you need). I'd recommend going to the IdentityServer docs and working through the quick starts in order as shown below:
This will give you a good start but you'll then need to go away and research APIs more generally, there's a tonne of good info online about building (RESTful) APIs. You may find it useful to sign up to something like PluralSight and work through a couple of their courses, they're often very good.
One other thing to bear in mind is that IdentityServer is for identity, in other words Authentication and not specifically for Authorisation so you may need to add something for this. You can of course use a users identity for authorisation purposes but in most cases you'll probably need to augment the info you store about their identity to authorise them for access. See this link for more info around this topic.

Shiro/Stormpath via REST

I'm new to Shiro. We are attempting to use Shiro with Stormpath. I've been trying to dissect the examples to come up with a solution to what I want to do, but I'm unsuccessful so far.
For now, I'm simply trying to create REST services to do what I want, and I'll tie a real client in later. This is what I'm trying to achieve as my first step:
I want to have a client hit a REST endpoint (login) on my server. My server would authenticate, and return a JWT to the client. This JWT would then be used to access secured endpoints on my server. (I have written Java code that can successfully authenticate against Stormpath).
My problem is the JWT. I expected that a JWT would be created for me, or at least easily accessible. I can't find a way to get one. I have seen sample code on how to build one, but that doesn't seem like the way I would expect to acquire one.
I have run through several examples, but most seem to deal with JSP interfaces, and I can't seem to make the leap to what I'm trying to do.
Is this approach reasonable? Any guidance is appreciated.
Edit 1
I now have a Java client that can authenticate using the Shiro servlet and retrieve a JWT. I have this running as a deployed application (war) in GlassFish. My next step is to use that JWT to authenticate against a different application that has my REST endpoints. This REST application doesn't need to know anything about how to authenticate - I just want to pass the JWT along in the call to a given REST endpoint and use Shiro (via annotations) to control access to the endpoint (if that is indeed possible). All of the examples I can find seem to be "all-in-one" examples (bundling JSP with Shiro/Stormpath configurations, etc). I'm trying to determine the minimum working configuration for securing REST endpoints and I'm having difficulty determining which pieces of the configuration I need.
Edit 2
I am using the Stormpath-Shiro-Servlet (as stolen from the Shiro Servlet example) as my authentication back-end. Using my Java client, I am sending a login request to the servlet, and I am indeed getting back a JWT. However, I am not able to successfully use the JWT to access my other rest resources. My rest calls result in this error:
org.apache.shiro.authz.UnauthenticatedException: This subject is anonymous - it does not have any identifying principals and authorization operations require an identity to check against. A Subject instance will acquire these identifying principals automatically after a successful login is performed be executing org.apache.shiro.subject.Subject.login(AuthenticationToken) or when 'Remember Me' functionality is enabled by the SecurityManager. This exception can also occur when a previously logged-in Subject has logged out which makes it anonymous again. Because an identity is currently not known due to any of these conditions, authorization is denied.
First, I don't understand why the servlet 'login' doesn't actually log me in and give me non-anonymous principle? Second, I am attempting to do everything on a separate client, so I don't have access to Subject.login (is this a correct assumption?).
Take a look at this example from github/stormpath-shiro
The JWT creation is managed for you by the Stormpath API. If you start up one of the examples, (the servlet one above, or the spring-boot-web example), after login, you will have a JWT cookie. There is background info in this blog post.
I'm working on releasing strompath-shiro now, but figured I'd include these link here so you can start looking.

MeteorJS Removing insecure Security Flaw?

i know this is a question that has been asked many time. but im still concerned about best practice when trying to develop secure code in meteor.
i know you can prevent the client from being able to access the database with the command:
meteor remove insecure
my code currently adds, retrieves records by using Meteor.methods() so although the client is not able to insert data into a collection, it can use the Meteor.method() function. im concerned about holding the login details in the database because would this not mean that the client can use the Meteor.method() function to add/get/remove data from the database.
the client being able to call the Meteor.methods() function seems to still keep the same risk doesn't it? or have i coded me work wrong?
if it help, here is a run down of what my work is doing:
application loads
client calls to get username and password from database
client sends login details to external server (over https) to initiate socket.io connection.
step 2 is the risk because it seems to allow the client to get the login details. once it has this, it uses the socket.io.js library and the api to my webservice to login. so meteor remove insecure doesnt seem to have secured it because get methods are still available in the Meteor.methods()?
being able to use these functions are quite crucial to retrieving data from the database, is there a way around this? what would be best practice for communicating to the database without exposing private data to the client?
Meteor's insecure package is just a tool provided by MDG to quickly prototype apps. It is not meant to be runned in a production app and some people think is a best practise to remove it all together from the start.
After you remove this package, if you want to interact with the database on the client using mini-mongo you must create the appropiate allow and deny rules on the collection. Here is the link for the Meteor documentation on this topic. The other way to interact with the database, is as you said, using Meteor.methods().
Meteor methods calls don't trigger allow or deny rules, since they are runned on the server. You must hardwire all the security measures you need on the Meteor Call by yourself. So it can be a security problem if you don't take the time to secure the call.
Regarding authenticating your clients I would suggest you take a look at Meteor's Accounts package. For example you can add this two packages for basic username/password authentication:
meteor add accounts-base accounts-passwords
Then you can just use the methods detailed on the Meteor Documentation.
I hope this helps.
Login
If you are using accounts-password, you can check the source here to see details of how it works. But here's a rough overview of it. When you call Meteor.loginWithPassword, the password is hashed client-side. Then a method is called with the parameters. The password is then salted and checked against the database server-side. If it matches, the client gets logged in. The client then subscribes to their own user data (Meteor.user()). The server only publishes their data. So everyone else's data is save.
Methods
A method executes code server-side. So they are generally secure. But you can of course write insecure methods. Just know, that you can't trust the parameters passed by the user.

FOSOAuthServerBundle Create Client

I'm currently trying to setup FOSOAuthServerBundle with my Symfony2 app.
Everything seems to be setup and functional, anyway I'm stuck after the installation.
What is the proper workflow with URLs to get the access_token ?
I tried /oauth/v2/auth, but sounds like I need to define a Client object first.
How to create/generate Client ? Clients are always supposed to be created manually ?
FOSOAuthServerBundle doc is great, but seems to skip all the usage workflow. Am I supposed to check the OAuth2 doc for this ?
Thanks !
In short, yes. You should be using the oAuth2 RFC to determine which workflow you want to use. In regards to client registration the RFC specifically states that the means through which a client registers is beyond the scope of the specification (https://www.rfc-editor.org/rfc/rfc6749#section-2).
With that being said I can give you some insight into how I did this. My application is a mobile phone application that connects to several services running on various servers. I'm also using the Resource Owner Password Credentials Grant.
The way I approached this was: when the application loads, the first thing it does is to check if it has an oAuth2 client id. If it doesn't, then it POSTS to a create client endpoint I've setted up with the meta-data I need. The endpoint validates the POST, creates the client and returns the client information. The application stores the client id and the process doesn't have to be repeated the next time.
Application loads;
Application checks for oAuth2 client id;
If there is one, the process ends;
If there isn't, it posts to http://www.example.com/client;
If we get a 200, store the oAuth2 client id.
I could have also created the oAuth2 client when the user created an account in the application, but I wanted to make the registration process as fast as possible. Creating the client would have added some extra waiting time to the process.
Check this: http://blog.logicexception.com/2012/04/securing-syfmony2-rest-service-wiith.html
It's quite simple to convert to Doctrine, whether you use it.
There's a command-line that does exactly what you need: create a Client!