Can this library verify the token with pem public key file ?
We don't verify the signature. It doesn't make sense to.
From a security perspective:
From a user perspective:
In the end, it just doesn't make any sense. Increased payload, increased code size (for both this lib and your own code), additional risks for naive consumers of this library. All to give a friendly message to a malicious user.
@escardin the big advantage of public/private signing is that both ends are able to verify the authenticity of the other end.
This library does not support this and there is another extension to JWT that covers how this should be implemented.
@charsleysa certainly so (though in this case, technically all you can do is verify the origin, since you only have a public key). I'm saying that on the client it doesn't really matter. The value of verifying that something is authentic must be balanced against what the user can do if verification fails and the cost of verification.
I am asserting that the user can do nothing, and that alone is enough to make verifying the signature mostly pointless (i.e. if they got the token from the third party that you sent them to, how do they know who the right third party is, how to get a valid token from them, and then how to put it into your app?). They could just... not use your app I suppose, or assume you are horribly compromised.
From a practical perspective, verifying the token will happen with every request against a token protected resource on your servers, and any data/code already on the client must be assumed to be compromised and visible. The token does not protect anything on the client and cannot do so. What benefit is there to verifying the token on the client in this scenario? If the user is malicious, it's not going to be even a small road block. If the source of the token is malicious, holy crap you have bigger problems, not to mention that you'll probably detect that you're getting bad tokens only from your server and if the client logs errors to your server (yet more work to do for something of dubious value).
Do the cost/benefit analysis for verifying the token on the client from the perspective of the developer, user and attacker, and then do the same for verifying the token on the server during api requests (note that you can't trust this request as a client to verify the token, it's only good for the server). I think you'll find that it makes sense on the server, where it is a trusted environment, and the public key can be distributed out of band, compared with on the client where it is an untrusted environment and the key has to come from another untrusted location.
@escardin you must remember that Angular2 has more uses than just simple web apps.
For example it can be used to build server-side apps, or pre-packaged standalone apps.
For any of these scenarios, especially on highly sensitive enterprise environments, it is very important that you are able to verify the authenticity of both end points.
Man in the middle attacks are a good example of how failing to verify both endpoints can compromise sensitive information. Of course things work differently when you serve up the app in a web browser compared to a prepackaged standalone app.
There are plenty of valid scenarios where public key private key would be highly beneficial and it is up to the development team to figure out when more secure techniques should be used.
If you've ever used Windows to log into an Enterprise account then you would have experienced a similar technique with Kerberos.
I don't think either scenario justifies making the common use case substantially more bloated.
You are the man in the middle between the auth server and the api server. In a server rendered view case, you have the resources and the control over the information required to make verifying the token (on the server) viable. In a pre-packaged standalone app, once again, all the info is available on the client, except the data protected by the api.
In terms of chain of trust, you get your application from somewhere 'trusted' via https. That code directs you to get your token from another 'trusted' server. You have to assume that those points are secure, otherwise you're screwed. What is then available on the client (whether browser, or stand alone app) is already compromised. Granted, in a stand alone app scenario the cost of sending a public cert is trivial, the client is still untrusted. SAML works the same way, using the client as a conduit for communication between two servers. The endpoints verify each-other, but the client is not an endpoint.
Btw. Given the amount of times banks have said enterprise level security to me, and then given me an absurd list of requirements for the security of my app, vs how unacceptably lax their own security is doesn't engender any faith in the statement 'highly sensitive enterprise environments'. The number of outs in PCI-DSS alone should give you a solid idea of how much BS such a statement is.
I would like to know what valid scenarios where verifying the token on the client provides more benefit than it costs. Genuniely, I do. I like being proven wrong.
In the case of a browser based application you are correct.
In the case of a standalone app you are incorrect as you would package in the public key along with the application.
The advantage of this is for the client to verify the server. This is useful in a use case where the standalone app is installed in a confirmed trusted environment and is then used outside of that environment.
If your transport isn't trusted then without this method you can't verify the server and therefore can't use the application without potentially compromising your information.
Also note that a JWT can be used for more than just a session ID/Key or just identifier information. It can be used to transport an API payload or a client side payload. You can also use JWT for custom handshakes between various differing end points.
The ROI of any development is subjective to the stakeholders. For a standard web app I would consider this to be overkill and redundant as it would only provide the illusion of security, but for a standalone app that deals with a companies vital data that is the core of their business that must be able to be used outside of their trusted environment this would be appropriate as they would definitely want the safety of not having their data compromised when the transport is compromised.
Okay, we agree that it doesn't have a place in this lib (it's like a 0.01% use case).
IF you're installing a standalone app, on a trusted computer, connecting to a remote trusted site, have verified your code hasn't been tampered with, and are in an untrusted environment, then I could see this adding a minute amount of additional security, that would be handled better by using https ('cause if you're using http, well you just gave your credentials away). If you're using https then you should be getting a valid token back from the auth server you just connected to. If not, that server is compromised and you can't trust tokens verified with a public key anyway. Still, if you're also using https then this would be completing the trust chain to the level paranoid corporations like to ask for.
I do use jwt to pass the permissions of the signed in user. I use it in the client to make it so they don't see things they shouldn't on the client, but more as a convienence, as I see no point trusting the token. On the server, I use the permissions to determine what to send back from the API without connecting to my auth server (though I suppose I could do that if 15 minutes was too large a window for a revoked token).
When using a token to pass data between endpoints, those endpoints need to verify the token. This is the same as SAML where you're using the client as a transport mechanism between two servers who may not be able to communicate directly.
Most helpful comment
@escardin the big advantage of public/private signing is that both ends are able to verify the authenticity of the other end.
This library does not support this and there is another extension to JWT that covers how this should be implemented.