Correct HTTP Status Code to be returned with OAuth Authorization Code grant type - api

A new website I'm working has the following components:
AngularJS/HTML5 Front-End
Web API Back-End that supports Front-End
OAuth Server - Authenticates user and provides tokens
The workflow for an unauthenticated user:
Views Front-End, which calls Web API to determine if authenticated
If not authenticated the user is redirected to OAuth Server
After successful authentication, the browser is redirected back to website with Auth Code
Auth Code is sent to Web API
Web API logic requests Access Token from OAuth server
A cookie is used to associate the token to the user
Additional requests send the cookie, which is used to authorize the user.
My question is what should I send for the HTTP Status Code for Step 1? Normally you send 401 for not unauthorized, but that is if you are using HTTP Authentication. Since the authentication is handled by a different server, that wouldn't make sense. 403 doesn't seem correct either because it implies a that the status will not change.
Should I just use a generic 400 or a custom 400.X code?

Although there is nothing wrong with sending HTTP 401 Unauthorized as a response in your case, a much better alternative would be to send HTTP 302 Found, which would imply that when the user was trying to access the front-end view, the applicable resource in this case (OAuth Server Url) was found somewhere else.
You can mention the OAuth Server Url in the Location header of the response, so the client would redirect the unauthenticated user to the intended location.
HTTP 302 Found
Location: https://oath-server-url.com

Related

401 Error When Making Basic Authenticated API Calls to X2CRM

We are encountering a 401 error when making basic authenticated API calls to the X2CRM endpoints (index.php/api2/Contacts). Unauthenticated API calls to other X2CRM VoIP endpoints are successful without issue, and basic authentication works on a test page in the same directory using the same PHP-FPM pool. API calls previously working successfully.
The problem is that API calls to index.php/api2/Contacts or similar endpoints in the X2CRM system are returning a 401 error with "missing user credentials." Basic authentication is working correctly on a test page in the same directory and using the same PHP-FPM pool, and unauthenticated API calls to other X2CRM voip endpoints index.php/api/voip/data/(phone number) are successful without issue. The credentials for the API calls are confirmed to be present in the database
We tried making basic authenticated API calls to the X2CRM endpoints (index.php/api2/Contacts, etc.) using Postman and cURL. We expected the API calls to be successful and return the expected data. However, we encountered a 401 error and the response stated "Missing user credentials". We confirmed that the credentials being used are valid and present in the database. We also tested a basic authentication on a test page in the same directory and it was successful, allowing entry into the directory. We need help resolving the issue with the basic authenticated API calls.
The response that you have shared
Missing user credentials
means that the credentials that you are trying to send are not being sent with the request.
If those credentials were being sent correctly, then, the error would have been:
Invalid user credentials
or, something else in the response.
Furthermore, the index.php/api is different from index.php/api2 so you will need to verify it in the api2 controller. You can send a request to the following Endpoint to verify if your credentials work with the builtin APIs:
https://<YOUR_CRM_DOMAIN>/index.php/api2/appInfo.json
Moreover, the documentation clearly indicates that 401 error is related to Authorization, so you will need to fix that first.

ID token usage when using "Log in with Google" in a mobile app

Suppose that I have a mobile app with a frontend and a backend server.
My understanding is that -- when a user logs in the app with "Login with google", the frontend sends a request to the google auth server, and gets back an ID token. The documentation says that the frontend can then send the token to the backend server to establish a session. I imagine that means the token can be used in session-based authentication?
If I were to use token-based authentication (as opposed to session-based), do I just attach the ID token in every server request, and have the backend verifies it each time when processing a request? this page suggests the ID token should not be sent to the backend API. Which leaves me wonder what the correct procedure is for token-based authentication when using log in with Google.
So my question is: Does my server need to create an access token from the ID token from Google, and send it to the frontend, so the frontend can attach that access token in the API requests for authentication?
Thanks
Login with Google is an identity provider (IDP) operation. A full OAuth solution, including an authorization server (AS) looks like this:
Mobile app uses system browser to redirect to AS
AS returns a redirect response to the system browser, which routes to the IDP
User signs in at the IDP
IDP returns an authorization code to AS
AS swaps it for IDP tokens and carries out validations
AS issues a set of tokens to the app. This includes an access token (AT) with whatever scopes and claims are needed for business authorization to work.
Mobile app sends AT in API requests
API authorizes using scopes and claims from the access token
So ideally plug in an authorization server, to get this out-of-the-box behaviour. Another option is to implement your own token service, and issue your own tokens. That is less recommended though, since it requires more detailed understanding of the underlying security.

keycloak, why does backend channels need a redirect url

I try to integrate my Python app(backend client) into the Keycloak system using openid connect, why do I have to fill the Valid Redirect URIs field? From my understanding for OAuth 2.0, the backend channel just need to exchange the code for id and access tokens in the Authorization Code Flow process
Why do we need a redirect URL here, shouldn't it only filled in the front end client?
Any Ideas?
We need it to restrict to what URL we are allowed to redirect to after a successful login. We do this to improve the security for your users, because it would be a big security problem if the provider could redirect to any URL after login.
The client which receives the authorization code and the one which exchanges the code for tokens must be the same client - at least from the Authorization Server's point of view. Theoretically you can have separate applications which handle parts of the OAuth flow, but they must be using the same client ID.
Ideally, the redirect URI points to an endpoint exposed by your Python backend. After Keycloak (or any Authorization Server) finishes authentication and authorization, it will redirect the user to that endpoint together with the authorization code. This way the authorization code will go straight to the backend client, the frontend app will never have to handle it. By registering the URL you want to make sure that no one performs authorization using your client ID, but asks to send the code to another application.

How does AWS Cognito redirect user to a http endpoint by passing his auth token to say he is authenticate user?

Is it possible that AWS Cognito redirects user to a http endpoint with user's access token if the user is authenticate user with Cognito? I need to implement this authorization flow in react web application. Basic idea is that user gives his credentials such as user's email address and password, then Cognito takes them to check if he is authenticate user or not. If he is, it should redirect user by passing the token to callback URL (in my case this is an http endpoint). After then the URL gets the token, it gives him access as final step.
This is possible. But you need to make sure your HTTP endpoint is able to redirect back to an UI page (Or React route) or render HTML after accessing the token retrieved in parameters.
Note: Simply having a HTTP backend URL won't work since the authentication flow requires to redirect the user to the application.

API Token Safety in Angular application

I'm building an Angular app with an API backend. On a combination of pieces of advice, I built the API with a flavor of token authentication. The flow is roughly as follows:
POST to login endpoint with credentials
Validate credentials and authorization, then generate a new token
Return token to client
Client uses token via HTTP Basic to access API resources
This is all working well. The problem arises in creating a session based on this token. I don't believe I should simply hold the token on the client in a cookie, but I do need a session to persist between page refreshes, etc. My Angular app is stateless and completely populated via API calls.
I'm looking for a recommendation as to hanging on to this token on the client. I feel there's danger in holding the token in a cookie because the cookie could be stolen and simply used to authenticate as someone else, but perhaps this is incorrect.
Thanks in advance for your assistance!
The only known way for me to identify a user is to use some token on the client.
HTTP is stateless and can't know which request is coming from which user (browser). You can't identify the user by his ip address (many users are behind a router and share a connection). You could try browser fingerprinting, it can work on some browsers but not on all.
I would recommend using a cookie to store this token on the client.
They are send to the server on every request and you can do some protection to keep them from getting stolen.
To protect this cookie from man in the middle attacks you need to use an encrypted connection over HTTPS to the server.
Set the following attributes on the cookie:
HTTPOnly: cookie can't be accessed by javascript (XSS protection)
Secure: cookie will only be send over https
Path: cookie will only be send on specified path e.g. /login
I would also define an expiration date on the cookie, so the cookie is invalid in like 2 days or something.
But you are right. If this token gets stolen someone else can login as this user.
Since its an Angular app, I'd assume all authenticated methods will only be served to ajax requests (you can tell your server to only respond to ajax) in which case CORS will help you.
The only way to be completely secure is HTTPS, however this method is probably more secure than you think. Read up on CORS a bit for more info, but essentially the idea is that servers will only respond to ajax requests coming from html pages that were served by that same domain.
Pre-flight OPTIONS requests are often sent to verify this. The browser sends an OPTIONS request with an Origin header (the origin of the page) before the actual request. If the origin matches the domain of the server receiving it, the subsequent request is allowed. Otherwise, it violates the Same Origin Policy and will be rejected.
This prevents someone from sniffing out the token and sending a request with the token from a page that your server didn't serve (like something running on the hackers local machine).
If you are doing credit card transactions or anything super secure, you should use HTTPS though.
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing