Can I Use JWT(JSON Web Token) authentication to our new REST API? - authentication

My authentication calls an API of the other server, I don't have a database table(The username and password does not exist on my server).How do I use JWT authentication in this case?
Thanks.

When You try to implement your own authentication server, you have to have a database with the username and passwords.
But after the user has its JWT Token, it can authenticate itself with it to your API Server, as long as the expiration time has not passed and the signature secret is shared between your auth and API Server, since you need to check if an attacker might have modified it.
After the expiration time has passed your client needs to issue a new token. You would usually use a second refreshToken which has a longer expiration time, and is checked against a DB to issue a new accessToken.
You could implement this yourself, but I would highly advise you to use technologies like OAuth2 since OAuth is used across all major brands like Google, Twitter, Github etc and is well tested against vulnerabilities.

Related

Where to store tokens obtained through OAuth2 (OpenID Connect)

I build an application that uses some Identity Provider (Auth0, FusionAuth, Azure AD, AWS Cognito) on user's choice.
I'm using Authorization Code flow.
And i faced issue with storing tokens.
I want to use Identity Provider to only user's sign in, i do not need to store who is the user (name, email etc.). I just need to authenticate user and be sure that user come from Identity Provider that i can trust.
So i have 4 questions:
Do i need to store tokens if i am not consider to use them to make requests to the Identity Provider.
If no goto 4 question. If yes i want to know what the best way to store them (save in session with db or just send them as accessToken for Header and refreshToken in cookie)
How i can validate access token, because as i know access token may or may not be JWT. Make request to IP on each request is not the best way, because of amount of requests.
Should i use my own created pair of access and refresh tokens to validate requests from Front End.
I'm only recently started investigate OAuth2 and will appreciate any answers.
As of now i have this flow:
From Front End(FE) user redirects to the Identity Provider(IP) to sign in.
IP redirects to the Back End(BE) with code.
BE make request to IP to obtain tokens.
BE validates that authorization is valid (via nonce and state).
BE redirects user to the FE with refreshToken in the httpOnly secure cookie and accessToken in query to store it in localStorage.
When FE make request to BE i validate accessToken(JWT) using jwks.
In OAuth you should not generally have to implement plumbing to build your own token stores. Eg tokens can be stored in strongly encrypted HTTP only SameSite=strict cookies. However you have to stay within cookie size limits. The best way to do this is to issue opaque tokens (such as UUIDs) to internet clients. The Phantom Token Pattern has more info on this.
You should not use foreign access tokens in your own APIs. As you are discovering, you may not be able to validate them. Also they will not have meaningful scopes and claims and you will not be able to authorize API requests properly. Instead issue your own tokens for your own APIs.
AUTHORIZATION SERVER
It is possible to issue your own tokens in code but this is not recommended. Instead, the preferred option is to use an Authorization Server. One option is the free community edition of the Curity Identity Server.
This component will take care of connections to Identity Providers for you. It will then issue tokens for you, so that your apps and APIs only ever deal with tokens from a single provider.

Can RestSharp obtain an oauth2 access token from IdentityServer/DuendeServer for a user programmatically if given username/password?

We have Duende server for our UI and users provide their username and password and obtain an access token that is then used by our SPA app to call api's with the access token issued by our identity server.
I'm in a situation where I need to call the same API from a script and was wondering if RestSharp has some capability to obtain an access token if provided certain information (perhaps the users email/password etc that are typically entered into an interactive website) ?
I see that the RestSharp has some OAuth related "authenticators" but the documentation is unclear exactly what they achieve. I also dont see it mentioning anything about an email address and password.
I'm wondering if theres an option that is different than me generating a JWT elsewhere and supplying it directly to restsharp. I'd love if there was a programmatic way to generate the token directly from the IDP.
RestSharp documentation doesn't make it secret about how authenticators work. Both OAuth2 authenticators only add the necessary header or query string using the token you provide, but they don't request the token.
Duende server documentation explains in detail how to get a token based on the password grant (which is using the username and password).
Although the OAuth2 spec is stable, each API vendor has its own limitations. For example, Twitter API v2 only supports the client_credentials grant type. Therefore, it's not easy to create a generic OAuth2 client.
Still, it's quite easy to amend the Twitter authenticator sample from the docs and extend both request and response models to support the Duende server token request endpoint.

Storing client secret on client side

I'm using an external service called auth0 in order to get an access token and let my users use my api. Auth0 is using Oauth2 protocol.
In short The user adds a username and a password, I'm doing a call to auth0 by using a client_id (apps have an id) and client_secret and I get an jwt access token in return. Then from there I carry this access token to have access to my own api since I can check its validity.
I have been looking around about how secure it is to store client_id and client_secret on the client side (e.g. web (javascript)/mobile (native or hybrid with ionic)) and everybody was saying that it's not secure since everybody can reverse engineer the code and get the client_id and client_secret. Ok...I can take it...what Can I do with them if I don't have credentials in order to get the access token?
Given that I don't want to store the client_id and the client_secret, one solutions I have thought is to make a direct call to my api (Java) with the credentials and then my api make a call to auth0 and return the corresponding access token. In this way the client_id and client_secret is stored in the backend and somebody cannot get them easily. Is that safe?
However I have some endpoints, e.g. creating use account, sending sms for phone validation etc, that cannot have credentials. How do I protect the api in such case? If I can't store my own access token on the client side how could I get an access token and access my own api without credentials?
Thanks
One possible solution that OAuth spec suggests is that you could have three different servers for your application.
client-side
backend server and an additional authentication server.
The preferred way of doing this would be that the client would send the user credentials to the authentication server. The authentication server would be a back-end server which contains the client secret
The authentication server will authenticate the credentials and return back the token.
The client will then use the token obtained from the authentication server to access the resource API server.
If you wanna know more check out this video
https://www.youtube.com/watch?v=rCkDE2me_qk
In my opinion you are almost certainly using the wrong OAuth flow. I use Auth0 with Ionic as both a web app and a native Cordova app. I don't have the client secret in my client code at all.
If you follow the Auth0 quickstarts (https://auth0.com/docs/quickstarts), you should be choosing (Native/Mobile App) if you are deploying to app stores, and (Single-Page App) if you are deploying the web version of Ionic. From there you can pick Cordova (for native) or Angular (for SPA). These should give you instructions that implement OAuth flows which DO NOT require your client secret. My guess would be you are referencing a "Regular Web App" quickstart, which runs server-side and CAN safely hold the client secret. That's not the world you're coding in if you are using Ionic Hybrid/Native.
I would consider wrapping the call to Auth0 into your own server side implementation as safe. Your API takes user credentials and then calls Auth0 and this way your client_id/secret are secure on your server and the client can be reverse-engineered all the way without compromising your security.
Regarding the other APIs which cannot have credentials you are pretty much out of luck. Their very use case is to be used by an unauthenticated third party, so at least the account creation API cannot really be protected. However you can still use some nicely designed constraints to limit the attack surface. E.g. you can require an email address/phone number to register and you will not allow the same address/phone number twice. If you set up your process that you first need to confirm your email address before you can validate your phone number this will make the life of an attacker a lot harder. He would need a real working email address, and some automation to receive your confirmation mails before he could get to call your SMS service. You could also rate-limit the service per IP-address so an attacker cannot cause your SMS cost to skyrocket by issuing a lot of calls for SMS validation in a short period of time.

OpenId Connect renew access_token in SPA

Trying to implement OpenId Connect in Web Application consisting of following components
Identity Provider
Resource server
Single Page Application acting as Client.
Identity Provider and Resource Server are the same application.
SPA use Password Flow to get access_token and stores into the cookie. Storing access_token into cookie has it's security threads, but's it's a different story.
Problem
access_token issued by IdP is expired after 30 min and SPA needs to renew token without asking users for credentials again.
Solution
IdP returns refresh_token along with access_token. Whenever SPA gets 401 from Resource Server, it sends refresh_token to IdP and get's new access_token back.
Problem
Sending refresh_token to SPA is bad practice.
A Single Page Application (normally implementing Implicit Grant) should not under any circumstances get a Refresh Token. The reason for that is the sensitivity of this piece of information. You can think of it as user credentials since a Refresh Token allows a user to remain authenticated essentially forever. Therefore you cannot have this information in a browser, it must be stored securely.
Suggested solution
When the Access Token has expired, silent authentication can be used to retrieve a new one without user interaction, assuming the user's SSO session has not expired.
I think Silent Authentication is not applicable to Password Flow when IdP and Resource Server is same application. access_token issued by IdP is only piece of information which can be used to authorize against Resource Server/IdP after its expiration, how a client can convince IdP to issue new access_token? (without sending refresh_token)
Found angular-oauth2-oidc library which uses refresh_token to renew access_token.
What is best practice/solution in this case to renew access_token?
technical details
Identity Provider - ASP.NET Core + Openiddict library.
SPA - AngularJs application.
Single page applications must not receive refresh tokens. That has been established rules in OAuth 2.0 and OpenID Connect.
One good option I see here is to use Implicit Flow. This will establish a front channel session from your browser to Identity Provider. With password grant type you do a back-channel call (POST), so you don't get such session.
Usually this is a cookie which points to information about previous logged in status (these are identity provider specifics). With completion of the flow, SPA will receive the access token. As you figured out, it will expire. But once that happens, SPA can trigger another implicit flow, but this time with prompt query parameter.
prompt
Space delimited, case sensitive list of ASCII string values that
specifies whether the Authorization Server prompts the End-User for
reauthentication and consent. The defined values are: none , login, consent and select_account
If you identity provider maintain a long lived session (ex:- few hours or days) or if it maintain a remember me cookie, SPA could use prompt=none making it to skip login step from identity provider. Basically, you are getting browser based SSO behaviour with this.
Using the Resource Owner Password Credentials flow defeats the refresh token storage argument: instead of not being able to store the refresh token in a secure place, the SPA would now have to store the Resource Owner credentials in a secure place (assuming you want to avoid requesting username/password from the user frequently). The Implicit grant was designed for usage with an SPA, so it is better to stick with that.
Further to previous answers, the latest OAuth working group guidance for SPAs no longer recommends use of the implicit flow.
If you have simple, shared domain app (IdP, RS and client on a single domain) then you should consider not using OAuth at all. From the doc:
OAuth and OpenID Connect provide very little benefit in this
deployment scenario, so it is recommended to reconsider whether you
need OAuth or OpenID Connect at all in this case. Session
authentication has the benefit of having fewer moving parts and fewer
attack vectors. OAuth and OpenID Connect were created primarily for
third-party or federated access to APIs, so may not be the best
solution in a same-domain scenario.
If you are using OIDC/OAuth in a SPA, they recommend the auth code flow with PKCE.

What is the function of Twitter's verify credentials API?

I just implemented sign in with twitter for my webapp. At the end of the OAuth 3-legged flow, I needed to retrieve the screenname & avatar pic for the user. All I had was the twitterid e.g. 3546735
So I performed a GET http://twitter.com/users/show/3546735.json
No security is required for this method, although it is rate-limited.
Recently I've read about another api method called verify credentials
Why should I call this compared to the simple GET above ?
One use of account/verify_credentials for OAuth is it gets the logged in users profile information without affecting the rate limit.
Update: verify_credentials now counts against the users rate limit.
It's of little use to you since you're already doing OAuth. It would provide the credentials in a single request, which can be easier to implement in some applications. Stick with OAuth if you've already done the work.
I believe the verify credentials approach is being phased out. OAuth seems to be the preferred approach.
I felt the need to reply to this and contribute since I've been working and have struggled with the twitter oauth api.
in short verify credentials returns the authenticating users' profile given their access token and token secret.
the reason for this is because in oauth 1.0a flow; after the user completes authentication, twitter sends an oauth_verifier token to you which is used to exchange request tokens for access and token secrets. At this point you do not know the user but have their credentials(access token and token secret). You can verify credentials to identify the owner of these tokens.