REST authentication / authorization - authentication

I need some advices on how to secure my application:
I have a REST service, using Spring MVC 3
I have my client application, using Ext GWT 2.2
Users credentials are available on the server side only.
SSL available
REST services should only be used by authentificated users.
I have read about HTTP Digest , token based authorization, oAuth etc, but I need some clarification and advices on how to secure my application, and which methods are the best in my case.

here is the methodology we created for our applications, works very well, and is very secure.
this is a very conceptual explanation, there is a lot of code that backs this up, FYI
When user authenticates or creates account, the server returns an x.509 certificate, base64 encoded, that is unique to for the user. The server stores a copy.
Everytime the client needs to access the REST API, client creates a JSON string comprised of the following.
The Users Unique ID (UserID)
A GUID or UUID, that guarantees this call is unique,(CallID) (protects against replay attacks)
A Dictionary (collection of Key/Value) of each parameter of the rest call
we then encrypt that string with the x.509 public key, and encode it back to base64 string, and take this encrypted value and add the UserID to a json object we call the token.
we then put the token into header of each call, and call it something like: X-Auth-UserToken
On every call the server takes the token, looks up the users certificate based on the userID, then verifies that the encrypted part of the token can be decrypted with the private key that the server holds for the user.
once decrypted, the server takes the CallID and verifies that it is unique, against its own calllog db.
if it checks out, the user is authenticated.
once the user is authenticated, you can apply your own authorization rules based on the users uniqueID.
of course, all the above is over SSL.
let me know if you need me to drill down on any parts.

Related

Verifying a JWT that DNN (DotNetNuke) created in a microservice

I'm playing around with DNN 9 and it's implementation of JWT at the moment.
Their implementation is here - https://github.com/dnnsoftware/Dnn.Platform/tree/development/DNN%20Platform/Dnn.AuthServices.Jwt
I'm wanting to write microservices in Docker containers that all look back to DNN's SQL. However, I need to understand how to verify the JWT that will be sent via the client to make sure it hasn't been tampered. DNN's web api implementations do this automatically. The problem is I don't see how I can verify that the token is valid because there is no 'secret' that i have to add.
I would want to get the JWT from the DNN enpoint and use this in a microservice which isn't running with DNN but will be able to read the data from the DNN database.
Could anyone provide any input?
Thanks :)
If the services have access to the DNN database then you can use the validation as implemented by the referenced code.
It seems that the tokens are not real JWT tokens, in the sense that they are self-contained, though they are not real reference tokens either. The tokens are persisted in the database, but contain public data as well.
How this is implemented: the token is identified by a sessionId and the secret is a concatenated string, converted to byte array:
var secret = ObtainSecret(sessionId, portalSettings.GUID,
userInfo.Membership.LastPasswordChangeDate);
The data is a JWT. It contains a Header, a Payload and a Signature.
From the received token first the Header (and scheme) is validated. Then the RAW token is read, expiration is verfied and the existence of the SessionId is checked, which is added as claim (TokenId).
The final step is to lookup the user from the store (cache / database), using the SessionId:
private UserInfo TryGetUser(JwtSecurityToken jwt, bool checkExpiry)
{
// validate against DB saved data
var sessionId = GetJwtSessionValue(jwt);
var ptoken = DataProvider.GetTokenById(sessionId);
When the SessionId is not found, the token is not valid. Again expiration is validated.
And finally the received data is compared to the persisted token, line 423:
if (ptoken.TokenHash != GetHashedStr(jwt.RawData))
This should prevent the token from being tampered.
This means for you that you can use the same code for your microservices, provided that the services have access to the DNN database. Call ValidateToken(), which will return the username when valid or null when invalid.
An alternative is to publish your own JWT tokens like I described here. You can create a central API or use a fixed, shared secret. E.g. a certificate that is available to the microservices. In that case you are dealing with self-contained JWT tokens which can be validated using the default validators. And you don't need access to the database.

Encoding and Decoding API Access token with keys

I am planning to secure my rest API in django with a ACCESS_TOKEN.
When ever user is logged in using their username and password, once they are authenticated, I generate a ACCESS_TOKEN and passed to frontend be it Website or Native application. and then later used that ACCESS_TOKEN for further communication.
I am generating this token based on some user data and then encrypting this with public key. Later when application send this for in any request, I decrypt the ACCESS_TOKEN with private key and extract user data data and process the request. This is something similar to session where session data is in encrypted form in ACCESS_TOKEN and only private key and decrypt the ACCESS_TOKEN. This is what I am planning to do.
Please suggest me for following questions:-
1. Is is the best way to secure my REST API? I want to use my API in same way from Web-application(AJAX calling) and NATIVE application(Android/IOS etc) ?
2. What is the best way to expire the token? Do I need to keep track of access token at my end in order to expire them?
Also I do want to use the Oauth in my API.
Most people I see use JWT's that are signed but not encrypted so they store non-PI data like user_id or session_id. I guess you could encrypt it if needing to store personal information but I don't see any other reason. Assuming you are using HTTPS, then only the end client would have access to the information. Sounds like asking for trouble if the secret gets leaked so you would want a really good key rotation scheme since you may not even know its leaked until too late.
Many people using JWTs do so because they don't want a centralized auth server, thus the token is short lived like a few hours or days. If you need really tight control on expiring tokens, you can take a blacklist approach where a blacklist of JTI's (JWT Ids) are stored in a K/V to be checked against. https://www.moesif.com/blog/technical/restful-apis/Authorization-on-RESTful-APIs/

API desing – Is it ok to fetch user's data from auth token?

Let's consider this use case:
1) I call my API login endpoint with username and password and get my Auth token that I add to every consecutive request to the header as Authorization: Bearer <token>.
2) I call /current-user endpoint with no params, only with Authorization header. Server authorizes user using token and gets user's id from that token. Then he finds the user by id in database and returns it's data.
My question is, whether this approach isn't insecure. I'm wondering, what if I was an attacker and was calling /current-user endpoint using randomly generated tokens. Once I occasionally matched real token, the server would return me other user's data.
Isn't it necessary to store user id on client along with token and call requests using both? Eg. /user?id=<stored user id> with Authorization header and get rid of /current-user endpoint? After that some kind of ACL on server would determine, whether used token has allowed access to user with passed user id.
(I also found there are JWT tokens but I see the same problem there. As an attacker I would somehow manage to guess other user's token and server would return me his data)
For security purposes, it is normally assumed that the user id is known to the attacker anyway. For example, if the attacker already has or knows a legitimate account, she might be able to guess how other user ids are assigned.
Also, if your token is long enough and totally random, it doesn't really make any difference.
Look at it this way: let's say your token has length n, your user id has length m. Without the user id, the attacker has to guess n characters, with it included she has to guess n+m characters. If your n is high enough, you don't need those extra characters. Keep in mind that the effective length of the user id might be much shorter than its apparent length if your user ids aren't completely random, so the m added might actually be really small.
Is it possible for you to use digitally signed tokens? You could basically encrypt the token with the client's (or user's) private key and then encrypt the package along with plaintext userid again with the server's public key. That way only the server can decrypt the package and once decrypted, it knows who the user is. It can then use the public key associated with that userid to decrypt to the package and get the token.
As you havent provided much info on the application and the speed of authentication required or technologies you are using, it is difficult to provide any more info.

Json Web Token + User Authentication

I just implemented Json Web Tokens to my api, but I don't understand how to verify if the user that created the token, is the one that is making the request.
For example, I have the /user/login end point, and I received the user and password for login. Then I create a json web token with the user data inside, and return it. And here is my problem, how do I know that the user that create that token, is the one that is making the request ?.
I found several ways to verify this, for example saving the user-agent + ip of the user and only accept request for that token if the user-agent + ip is xxx, but I am not really sure that is the best way.
I hope you can help me with some tips,
Thanks for all
how do I know that the user that create that token, is the one that is making the request ?.
Because the JWT includes the user ID and is signed, therefore any alterations to the content will be detected. Possession of the token is proof of authenticity
The process of issuing and authenticating with JWT is more or less like this
Issuing new JWT
User performs and authentication using its credentials
The server validate credentials, generate the JWT payload including the user data and some fields such as expiration time or issuer, and signs the token with server private key
The client receives the token and store it (in a secure storage).
Authentication
User sends a request to server. The request includes the JWT, usually in headers or as url param
The server validates the signature with the key, and extracts the user ID to know the requestor. If the signature is not valid rejects the request
Any reason you can't use a standard like OAUTH2 and let the big boys handle security for you? Rolling your own security is usually very difficult to get correct and almost all the major players provide free OATH support.
That said, I'd be hesitant to lead you down a bad path, however I've been in your shoes before so if you must roll your own security, make certain you fully read all of what OWASP has to offer. They offer very detailed threat analysis and also give suggestions that will be invaluable along your journey.
OWASP Threat Analysis
EDIT 1
A good light weight and easy to implement standard is OpenID which as their banner explains is,
A Simple Identity layer on top of OAuth 2.0
See here for a very detailed explanation of how it works:
OpenID-Wiki

REST method for UI and API access

Folks:
This is a REST design question, not specific to any programming language. I am creating an application backend that is accessed via REST APIs. I would like to use the same APIs for both UI and API-based access. I am trying to figure out the best way to authenticate users so that I can reuse the same methods.
My current thinking on authentication is as follows:
API Users
These users get a user GUID and a pre-shared symmetric key. On each API request they include additional headers or request parameters that contain:
Their GUID
A security token that contains the user GUID, the current timestamp and another GUI (token GUID) concatenated together and encrypted using the shared key
Upon receiving the request, the server looks at the claimed GUID, retrieves the shared key, attempts to decrypt and verifies the token.
UI Users
These users will make a login request, supplying human credentials (userid/password). Once authenticated, a session is established backed by cookies and further REST calls are secured based on this session.
The Problem
What is the best way to write one REST endpoint that secures both ways: API access and UI access cleanly without too much duplication? I am looking to do the equivalent of the following, but perhaps more cleanly:
#app.route('/')
def hello():
user = None
if session:
user = get_authenticated_user()
else:
user = process_auth_headers()
# Do something with user
I am looking to code the server in Flask, but I am sure the solution will apply as easily to any REST-based server-side framework.
Looking forward to some insights from the community.
Thanks.
We use node for our server, but I think the method we use is pretty common. There are session libraries that express can use, and they can utilize pretty well any database to store session information. They use a cookie with a key that does a lookup on the database when the client comes in. The session data is created when the client authenticates, and the cookie with the client key is added to the browser. The clients GUID is stored in the session, it never leaves the server. We use that info when they hit the server to check if they are logged in, who they are, and what they can do. We have used both FB, (client checks FB, then sends the FB id and token down to the server, which then rechecks and sets up the session or rejects it,) or the old classic, email and password. This works well when you have to scale across multiple app servers, as session is independent of the server, it works for both mobile clients and the web.