Can anyone tell me the difference between basic authentication and JWT token? - java

So in our project I am responsible for the UI part which is in Angular 8 and the backend is developed using JAVA. Both will be deployed in the same windows server.
Currently we are using basic authentication for authenticating the user and accessing different REST URL's. I am new to this so I have not much idea about the JWT tokens.
So can anyone explain what is the difference between using basic authentication and JWT tokens and do we require JWT token when both backend and frontend are deployed in the same server?
sample code for user verification in current project using basic auth...
LoginAuthorisation(logindata: LoginData) {
let authrizationdata = logindata.inputEmail+":"+logindata.inputPassword;
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa(authrizationdata),
}),
observe: "response" as const,
withCredentials: true
};
const body = { "message": "Test Data"}
console.log(httpOptions);
return this.http.post<any>('http://*****************/home',body,httpOptions);
}

This is a really broad question but here goes.
What is basic authentication?
Usually what we mean with BASIC Authentication is HTTP's basic auth which is: In the context of an HTTP transaction, basic access authentication is a method for an HTTP user agent (e.g. a web browser) to provide a user name and password when making a request. In basic HTTP authentication, a request contains a header field in the form of Authorization: Basic , where credentials is the Base64 encoding of ID and password joined by a single colon (Wikipedia)
Bottom line: a client sends their credentials over to a server for validation.
What is JWT-based Auth?
That, however, is not a great idea. You generally don't want to send your credentials. Rather you want to send a token that represents your rights / entitlements to talk to the aerver. This is where JWT comes in. JWT stands for JSON Web Token. Your identity server generates a token that certifies the user identity, and sends it to the client. The client will send the token back to the server for every subsequent request, so the server knows the request comes from a particular identity.
Now it helps to understand JWT kind of comes from OAuth 2.0 and OpenID Connect which are authorization / authentication protocols built to avoid the "password anti-pattern" i.e. having to share your creds.
Have a look at sites like oauth.tools or jwt.io for more info.
JWT-based auth is becoming the de facto standard for API authentication rather than username-password.
Resources
https://jwt.io
https://oauth.tools
https://medium.com/#maison.moa/using-jwt-json-web-tokens-to-authorize-users-and-protect-api-routes-3e04a1453c3e

Related

Get access token using Spring Security with a specific use-case

Is this use-case supported for Spring Security 5, or something else, where we don't have to reinvent the wheel? Thoughts on how to (re)implement this better?
Details are as follows. 3rd party vendor supplied endpoints. We pull info from upstream source then forward to the downstream vendor. Only 2 APIs are required:
Request Access Token
Save Info
Both are actually being called via a gateway. We've been given specifics:
(A)
The token request requires Basic Auth (standard header - usual base64 encoded). Gateway User and Gateway Password are provided.
Credentials for request token are provided to us:
Grant Type = password
Consumer Id
Consumer Secret
Account User
Account Password
It responds with an access token and few other details we don't really care about and of zero value to our use-case.
There is no expires_in info in the response. But I've tested it multiple times to know it does expire. Not sure how long right now, I could do more tests to determine that.
(B)
The save request requires a different custom header for the same Gateway User / Password, then a Bearer Authorization header in the call to the Save Info API.
Right now, all implementations for above are using RestTemplate. Working fine already. But a token is requested for each save which is costly. Before writing any caching, or some other logic to wait XY minutes before another token request is made, I would appreciate any other options which may already be possibly handled via Spring-specific libraries or further advise on how to handle this scenario.
Apologies if this is not the right place to ask this, or it has already been asked before. Been searching for a similar use-case but can't seem to find one.
Thanks.
Try any one of the option
You can use OAuth2ClientContext which stores your access token.
final OAuth2RestTemplate restTemplate=new OAuth2RestTemplate(resourceDetails, clientContext);
You can create session & store your token & user details inside it.
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(user, null,null);
SecurityContextHolder.getContext().setAuthentication(authToken);
from option 1 Or option 2 you can then fetch existing token for each request at your Filter e.g. PRE_AUTH_FILTER
Then check if token expired - if yes request new token Or call refresh token
Check Oauth2 expires_in in below :-
https://www.rfc-editor.org/rfc/rfc6749?

How to prevent Rest web-service Authentication with stolen Token

As we know Rest services are stateless, General strategies to authenticate is using a token based authentication.
In login service it takes credentials which returns a token.
This token might be set in client cookies, and all subsequent requests uses this token to be validated and process new request if token is valid.
Now my question is how one can validate the token ? If someone has stolen the token and tries to access rest services with stolen token by just editing cookies then how can it be identified and restricted ?
We can never know if the token is fetched by valid user and same user is trying to access subsequent request. but what are the possible ways to make it more hard, like to verify if the request has came from same source ?
One general suggestion is to set aging for token/cookies, but it still not helpful till the age of that token/cookies.
Any suggestions would be appreciated.
I don’t believe there are any 100% fool proof methods of preventing access with stolen user tokens. How do you even know that the token is stolen in the first place? But from the top of my head you might want to consider following:
Accessing a REST service with the same token but a different user agent is suspicious. This can be recognized with the value of the User-Agent header. You might want to consider dropping such requests.
What if the IP address changes but the token is still the same? Well, maybe someone is using a load balancer and accesses the network over different IP addresses? Or he accessed a VPN with the same token/cookie as before? If you have no compunction dropping such requests, you might level up the security by checking the source IP address too.
In case of – say – JWT tokens, you will need a bit of infrastructure to handle the blacklisting. Follow this.
My current understand of the "most secure" approach to authorizing requests in the browser is to require validation of an HttpOnly SameSite cookie AND HTTP header (e.g. Authorization or X-CSRF-Token) in combination.
For example, when issuing the JWT to a browser, send the JWT signature in an HttpOnly SameSite cookie, and send the body (without signature) to the client to store in localStorage and submit in the Authorization header. When authorizing a request, combine the two back into the complete JWT and validate it as normal after that.
Alternatively, you can generate two JWTs with a field to distinguish them (e.g. the client one has "browser" in it, the cookie has "cookie") and require that both are valid and both identify the same user. One is sent in the Authorization header and stored in localStorage and the other uses the SameSite HttpOnly cookie.
Another popular approach is to store a CSRF token in a field in the JWT, and put the JWT into a cookie and require the client to send a matching token in a header (e.g. X-CSRF-Token).
All of the solutions effectively prevent XSS and CSRF attacks: XSS cannot retrieve the HttpOnly cookie, and CSRF does not include the HTTP header, so this blocks both attacks.
Note that you probably only want to apply this rule for requests from web browsers. For server-to-server communication, requests are not subject to CSRF and XSS attacks.
After struggling through various approach We found a solution explained below:
We store token (encrypted) in cookies on login request and for each subsequent request this cookie gets validated.
The problem was if someone replace the token in cookie with another valid token, as cookies are maintained by client browser.
Solution :-> Though token values were encrypted, it was representing only one value, So if one replace whole encrypted value with another valid encrypted value it can be hacked.
So to solve this we have added another cookie which was combination of multiple values.
e.g.
Cookie 1 -> encrypted token
Cookie 2 -> An encrypted object containing information like username+ some other user context details+token
So in case of Cookie 1, it was easy to replace with another encrypted value as it was representing only one token though it was encrypted.
But in case of Cookie 2, it was containing object with multiple values, so only token value can not be modified, encrypted and set back in same cookie.
Before authentication We are doing decryption whole cookie 2, fetch token part from it and validate the token part of it against cookie 1.
That has solved our problem !!
Thanks all for your time and guidance.
You can use jwt is an Internet standard for creating JSON-based access tokens that assert some number of claims. For example, a server could generate a token that has the claim "logged in as admin" and provide that to a client. The client could then use that token to prove that it is logged in as admin .
How it's working ?
First it's contain private key generated by developer :
let us have this key :sfcqw#sav%$#fvcxv*s_s515 and this one called private key , and we also have a public key this the public key generated depended on user data and private key and it's impossible to know what is contain if you don't know the private key .
to more explain :
public key :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.plpJkAcgrgCIsoRyV2kjGsvWF6OsXU1mD785OSWTH4o
we have the above key generated by our private key : sfcqw#sav%$#fvcxv*s_s515
To be more clear going to this website : https://jwt.io/ and try to past the public key without put secrite key like picture and you will understand everything .
To me, there was no way to prevent the access from being stolen JWT token except
setting a short timeout for the token
more secured at the HTTP request level by only allowing specific `User-Agent. See more
more secured at the HTTP request level by customizing the header key for the organization, e.g My-X-Auth = Bearer <token> instead of Authorization= Bearer <token>
more secured at the HTTP request level by restricting trusted urls/domains, e.g X-Content-Security-Policy. See more

Google OAuth returning invalid_grant Incorrect token type

I get a valid code on the client side login of my application using angularJS Oauth Module GAuth.checkAuth(). and then GAuth.getToken().
The code is valid only for 1 hour and any API like GoogleDocs,Gmail accessed after 1 hour fails and needs relogin.
To overcome this I am trying to send the code to the server for getting AccessCode at Server so that I can send same with requests to GoogleDocs, Gmail etc
GoogleAuthorizationCodeTokenRequest req =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
// "https://accounts.google.com/o/oauth2/token",
"901142925530-21ia7dqnsdsdsndnsnnnfdc9cm2u07.apps.googleusercontent.com",
"6NSvw0efghyuuG8YGOBWPln79n",
authCode,
"http://localhost:8080");
req.setGrantType("authorization_code");
//req.put("refresh_token", authCode);
//req.put("access_type", "offline");
GoogleTokenResponse tokenResponse =
req.execute();
tokenResponse.getAccessToken()
Where authCode is the code I received in GAuth Token
But the call is failing and in response I get
400 Bad Request
{
"error" : "invalid_grant",
"error_description" : "Incorrect token type."
}
Any help is highly appreciated!
When the user first authenticates your application you are given an authorization code. You then need to take this authorization code and exchange it for an access token and a refresh token. Once the authorization code has been used it can not be used again.
grant_type=authorization_code
Denotes that you are asking Google to verifiy that your authorization code and give you a new access token and refresh token.
It sound to me like you are taking either the access token returned from that request and sending it to grant_type=authorization_code end point which is not going to work its the wrong type of code. hens the error you are getting of
400 Bad Request { "error" : "invalid_grant", "error_description" : "Incorrect token type." }
You will need to take the refresh token you are given. If there is one I am not sure that you can even get a refresh token from AngularJs. You can get one using java though.
A refresh of an access token in pure rest will look like this
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Note the &grant_type=refresh_token. If you are using the Google api java client library it should handle all of that for you. However your tagging is a little confusing its unclear if you are trying to do this in java or angularjs which I do not believe will allow you to use refresh tokens. Again I am not an angular dev I could be wrong on that point.
Anwser:
You the code you are sending is not an authorization code. Only an authorization code can be sent to grant_type=authorization_code. Solution: Send an authorization_code
Types of Google codes and tokens:
There are three types of codes or tokens you should be aware of with Oauth2.
Authorization code.
Refresh token
Access token
When you request access of a user and they grant your application access you are given an Authorization code. The Authorization code is short lived it probably less then 10 minutes and it can only be used once.
The Authorization code is used to get the initial access token and the refresh token from googles authentication server. by using the grant_type=authorization_code
Access token are good for about an hour. They are used to make calls to google APIs
https://www.googleapis.com/plus/v1/people/me?access_token={your access token}
You can use the access token as often as you want during that hour assuming you don't blow out some quota.
Refresh tokens are used to request a new access token from the Google authentication server when the access token you have current has expired or you just want a new one. here the grant_type=refresh_token is used to request a new access token you are essentially telling google I am sending you a refresh token you know what to do.
additional reading
I have a coupe of tutorials that might help you out Google 3 Legged OAuth2 Flow and Google Developer Console Oauth2 credentials
Also helpful when learning Oauth: The OAuth 2.0 Authorization Framework

How to send back a JWT token with HttpURLConnection in java?

I am using an API to get some information. At the beginning of each session you need to get a JWT token to be able to send requests to the API. After I've got the token and I try to send a request, I get an error saying I'm unauthorized, which is fair since I did not attach the token in my request. The problem is that the documentation for the API does not explain how to do this, and I haven't been able to find it anywhere else either. How do I do this? I am doing this is Java and is using their own HttpURLConnection. Hopefully you understand what I mean.
Thank you in advanced!
It depends on how the web-service (API) wants to have the token represented.
Common are:
HTTP request headers (problem for XHR requests)
query parameters (bad idea because of caching/logging)
form fields (not universally useable)
URL segment (bad idea because of caching/logging)
certain cookies with the token as value (transparent) or
authentication header (typical)
The Authentication headers as defined in HTTP RFCs are typically be used with the Basic or Digest authorization scheme. In case a string (token) authenticates the bearer of that token, the "Bearer" scheme is used (for example defined for OAuth2 in RFC6750).
You would use
uc.setRequestProperty("Authorization","Bearer " + jwt);
for this.

Passing API Key, usr/pwd in httppost URL. is it permitted? txtwire API

I am trying to use txtwire (for sending SMS) and they provide a httppost service mentioned below. I know it is "https" but still.. is it OK to pass my API key, userName & Password in the URL?
There is no Basic Auth Mechanism because service expects everything in URL.
https://api.txtwire.com/httppost?phone=18885554433,18885554422&username={username}&password={password}&api_key={api_key}&code=12345&keyword={Group Keyword}&message=testMessage
My only other option is to user their SOAP web service. which is cumbersome and i would prefer RESTful. would SOAP be better if passing credentials in URL is not preferred?
Here is the API : https://api.txtwire.com/documentation/class_w_s___message.html#a99faeee5de80610649b184f180098982
will appreciate any help.
Is it permitted? Well, this is a question that API service provider should answer. It looks like that textWire API doesn't have any issue with it.
For the sake of security, personally, I don't like to post/get credentials without being encrypted. Even with Basic Authorization, there is a way to add encrypted username and password as request header "Authorization". Something similar to the following:
headers['Authorization'] = 'Basic '+ <encoded Base 64 String (username + password)>
Perhaps you want to find out if textWire API support such approach.
You should be ok for both of them, from what I can see they're using an SSL+TLS certificate.
From a more technical point of view, passing the password as part of the query string (RESTful), passing it in the request body (SOAP) or passing it as a request header is actually the same approach (don't forget that basic authentication trasmits the credentials as username:password sequence encoded with base64), because the password itself is being transmitted along with the message itself.
It's a possibile practice, but I would not raccomend it. If I were to expose an authenticated service I would use a username+HMAC signature combination, or maybe an autentication token of some sort.

Categories

Resources