We are implementing JWT to allow our client side to authenticate through our separate authentication server.
The client posts the username and password to the authentication server, receives a JWT and then logs in to the main site with the JWT.
Clearly, the token includes the username and some other non-secret information.
The question is if to use JWT to pass secret information and how.
Here are a few options that might be considered:
Don't do it. Have the main website server call a back-end API with the authenticated username to get the information it needs.
Pass the information as Private claims encrypting the values with a symmetric encryption and sharing the key/pass-phrase between the main website and the authentication server.
Encrypt the entire token.
Are there any best practices here? what are the ups and downs of these options?
You shouldn't use JWT for passing secret information.
These tokens are usually signed to protect against manipulation (not encrypted) so the data in the claims can be easily decoded and read.
If you need to pass sensitive information please look at JSON Web Encryption(JWE)
You should check JSON Web Encryption for this purpose
Related
I have an existing client, which calls a server, which in turn calls
https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword
With that, client POSTs to the server (and server, to Firebase) an unhashed password over HTTPS.
I would like to salt/hash the password on the client. I am at liberty to use the same algorithm Firebase uses. But I don't see a method for sending a hashed password to Firebase. And I have existing users who, of course, can't lose access with this migration.
To sign in to Firebase Authentication's email/password provider, you have to send the password in cleartext over a secure connection. There is no way to change this.
This is not a security risk to send the password in cleartext, as the secure connection is end-to-end encrypted, so the only two sides who can see the data can already access it anyway. If somebody can intercept the data and decrypt it, it means they have access to the certificate of your secure connection, which is a much broader security risk.
Of you want to sign in with a password in a different form, the only way to do that is by implementing your own custom provider on top of Firebase Authentication.
How is using a JSON Web Token more secure than an opaque session token, In both the scenarios the tokens are first sent to the client and then verified on the server when a client requests a protected resource.
There are several reasons people say JWTs are more secure. I’ll list them and also give you reasons why that might not really be the case as it swings both ways.
JWTs can be signed using a secret with secure algorithms like HS256 and RS256. A comprehensive list can be found here. On top of that, you can also encrypt the payload of the JSON Web token. However, session tokens can also be generated securely with a top-notch algorithm and stored in a signed cookie.
JWT can either be stored in a cookie or Web Storage( local/session Storage ). If you are not storing your JWTs in a cookie, then you are not vulnerable to CSRF. And you can decide to send them through the Authorization header for every HTTP request. However, there is still a caveat. Javascript is used to access the JWT from the Web storage, which still leaves you open to other forms of attack such as XSS (Cross-Site Scripting). Worthy of mention is that it is easier to deal with XSS than CSRF.
In a situation where your JWT has been tampered with, you can revoke or blacklist the token. This involves making a call to the DB every time you want to perform this kind of operation which I won’t advise you to do. The preferred option is to use short-lived tokens.
In the case of OAuth, opaque tokens otherwise known as bearer tokens are random strings that will be stored in some kind of hashed storage on the server together with an expiration, the scope requested (e.g. access to friend list) and the user who gave consent. Later, when the API is called, this token is sent and the server lookup on the hash-table, rehydrating the context to make the authorization decision (did it expire? does this token have the right scope associated with the API that wants to be accessed?). The main difference between opaque tokens and signed tokens(e.g JWT) is that JWTs are stateless. They don’t need to be stored on a hash-table.
Conclusion
The libraries used to sign and encrypt your JWTs should be secure to ensure your authentication process is also secure. You should also use cookies as storage mechanism rather than using them for login. You can argue that there are more benefits to using JWTs like they are easier to scale and they can be used in OAuth cases which you can find in this article. At the end of the day, In my opinion it simply falls on the developers’ reasoning/logic to ensure the right steps are followed to make an app secured regardless of what form of token is used for authentication or authorization. Use case is also key in this context!
So I have a web Api that authenticates users by username and password. The clients talking to the API will android phones that have an internal app on it to get / send some data from / too the api.
I have hashed passwords in the database with a salt. The connection between the client and the API will be SSL.
Now on the website (MVC) I log users in by generating a new hash and matching this against the hash in the database.
The some of the android devices will have a config file that locks the app to a specific user. Now I rather not store the password in plain text on the device and would like to encrypt the password.
The question now is what would be the best practise here on comparing the hashed password. I dont think its save to just send the plain password to the API or is it?
It's safe, because you're using SSL.
Basic authentication isn't acceptable for plain-text requests, but since HTTPS encrypts everything, it shouldn't be an issue.
Storing the password is a completely separate concern, as you've noted, and that should be encrypted as well, which it sounds like you'll have Android do for you. The only consideration is that you will have to do a reversible encryption to be able to send up the password itself to your API.
Basically:
(client-side) User enters creds
(client-side) Encrypt creds, store in configuration
(client-side) Read from config, decrypt creds
(client-side) File HTTPS request to API with Basic authentication type, using decrypted creds
(server-side) Hash (one-way encrypt, basically) the password, compare against database
That sounds like exactly what you've got, and I see no problem with it.
That all said, just for what it's worth, I'd be tempted to implement an OAuth 2.0 server for this particular use-case, so you don't have to think about persisting the password at all. That's a pretty big undertaking (sort of--it doesn't take too long with those instructions), and you should evaluate it on a case-by-case basis. But any time I have to worry about API authentication, I generally wind up either going with that, or wishing I had.
I would consider using something like JWT (JSON Web Token, http://jwt.io). You can have a client authenticate against your API, and if they provide the right credentials you can issue a token to them, which they can persist on local storage. They would then provide this token in the header of any API requests that require authentication. You can use OWIN middleware to intercept requests, check/validate the token and let the requests through to your controllers if you consider the token to be valid.
I'm developing a REST web API that will be used by mobile app clients. I don't want any other client to be able to access the API. Should I just require a password/token that will be used by the mobile apps? Isn't there a way for people to find that password by decompiling my app?
Yes, you cannot create an app with a secret embedded and expect the secret to stay secret.
If you ship the app with the secret (token, user/pass, private key, etc), that information is available in the binary, and someone motivated could extract it.
The normal practice is to install the app, then let the user of the application log in, and store a unique credential for future requests.
You could use OWIN OAUTH where a user of the client is required to authenticate and a Bearer authorization token is returned to the client that must be passed in to all secure requests on the WebAPI (a secure request on the WebAPI uses the Authorize attribute)
Take a look at this link http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/#comments
I am using ASP.NET WebAPI for a web service that I am building. He web service will use the Identity service to authenticate users.
I am a bit stuck as to how to authenticate users externally. Our current system is very basic- we send a username and password in the XML request as a separate field and it is all done in 1 request.
From what I can see from looking on Google, the best way is to request a token from the Ali and then pass this token in subsequent requests. Is there a way where I can do it all in 1 request (that is, send to the API my request for data as well as the username/password or perhaps an API key in a single request?)
From what I can see from looking on Google, the best way is to request
a token from the Ali and then pass this token in subsequent requests.
Is there a way where I can do it all in 1 request (that is, send to
the API my request for data as well as the username/password or
perhaps an API key in a single request?)
I'm not sure why your web service want to know user's username and password in Token based Authentication.
In Token based Authentication, your web service should not ask for user's username and password.
Instead, user first verifies the user name and password using a token issuer that your service trusts.
Upon successful verification, the token issuer provides the user with a token. Once the user has that token, it uses it to call your service.
For that, you do not have to reinvent the wheel. Here is JwtAuthForWebAPI nuget package for OAuth2 and OpenId Connect.
It is not secure at all to keep sending username/password with each request, you need to configure your api to issue access tokens for specified life time i.e. 24 hours. To do so you need create and end point (/token) which accepts the username/password validate the combination then issue an access token.
The client which receives this access token is responsible to store is securely and transmit it with each request to an any protected resource using the request "Authorization" header using bearer scheme.
As well you can not do this in one request, you need to obtain the access token at the beginning the you keep calling your protected resources using this access token until it is expired.
You can read more about this in my detailed blog post about Token Based Authentication in Web API