I was wondering why my Authorization Header is not recognized. When I pass it to my server web app endpoint.
However, when I do it on my localhost it works well
These are my request headers:
PS.
I am using Django Rest Framewok on my backend and what you see is Google Chrome's Advanced REST Client for testing my APIs. Also please take note that the CORS HEADERS are allowed and Token Authentication is the method I'm Using as credentials for my endpoints.
Related
I’ve got a project using a Django backend, with Django Rest Framework to serve an API, and a Vue.js frontend SPA to consume the API. I’m running into some kind of CORS issue during authentication.
I’ve been using mozilla-django-oidc to implement the Authorization Code flow with Okta. This works fine pretty much out of the box, and if I navigate to the API in my browser, I can login to Okta and I get a Django session. I’ve also enabled SessionAuthentication for DRF, which allows the same session cookies generated by Django to be accessible by the SPA (both SPA and API are on the same domain), provided I login first directly through the API. This all works fine until the id token expires. In Django, when the id token expires, I get a redirect to https://example.okta.com/oauth2/v1/authorize?..., the Authorization Code flow completes and I get sent on through to the originally requested page. Where things fail is in an ajax request from the SPA to the API with an expired id token. I get the same redirect, but this time it fails due to CORS.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&nonce=X' (redirected from 'http://127.0.0.1:8080/api/X') from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I’ve tried to identify why it’s failing.
On local development, I’m running my API on 127.0.0.1:8000 and my SPA on 127.0.0.1:8080, so clearly the origins don’t match. I have Vue setup with a proxy so it looks like requests are coming from 8080, but the redirect_uri in the request to Okta is still using 8000.
When I deploy to a test server, I’m using docker containers for the API and SPA and a reverse proxy to route requests and also for SSL. In this case, the API and SPA have the same origin (I think). Yet I still get the same error message.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2Fexample.com%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&nonce=X' (redirected from 'https://example.com/api/X') from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If you notice, the redirect_uri is http, not https. I suspect that is why this is failing. Though I’m not entirely confident because if I navigate my browser to the API, I am on https, but the redirect_uri is still http, and it still successfully authenticates.
Any insight would be really helpful.
What am I doing wrong or missing here?
Am I approaching the authentication flow all wrong for an API+SPA app? Should I do authentication on the SPA instead? How does the API then know who’s logged in?
Edit: I have already tried adding the origins to the Security > API > Trusted Origins section in Okta configuration. No dice.
https://developer.okta.com/docs/guides/enable-cors/overview/
In Okta, CORS allows JavaScript hosted on your websites to make a request using XMLHttpRequest to the Okta API with the Okta session cookie. Every website origin must be explicitly permitted as a Trusted Origin.
So configure your Trusted Origins properly in the Okta client configuration.
Are you making an AJAX call to /authorize ? That could be the reason for the error.
As mentioned here, when making requests to the /authorize endpoint, the browser (user agent) should be redirected to the endpoint. You can't use AJAX with this endpoint.
In my Asp.Net Core 2.1 Web Api + Angular App setup, I am trying to reset user password token using identity framework. Token is generated by calling GeneratePasswordResetTokenAsync(), emailed and request is sent back from client, verified by ResetPasswordAsync. I have checked that the two tokens are same but still ResetPasswordAsync fails with Invalid Token result.
I am using PG SQL as database, and JWT for Authentication, The SecurityStamp is also not null, my client app is written in angular and served from a different web server than the one serving the web api. However when testing on local machine there is no problem.
I have enabled CORS in web api allowing any origin, however I have noticed that my client request contain
Origin: https://my-domain.com
Referer: https://my-domain.com/myangularapp
Please let me know if any info is missing, any help will be appreciated.
I will roughly describe the problem:
I have a React.js application, which authenticates using IDAM and receives a token. I can use this token to make requests to the backend API. Everything is fine regarding the interaction React.js <-> API.
Now I need to redirect to a Django application from the React.js application. I already have the authentication token, and I want to pass it to the Django application. I was thinking about putting the authentication header when doing window.open to open the Django url, but I realize that it is not possible to put headers with window.open.
How can I pass the authentication headers when opening a new url?
NOTE
The API and the Django application are not related (they are different applications).
The API is a REST API (implementation irrelevant), used by the React.js frontend to request data.
The Django application is "normal" Django application (no DRF), unrelated to both the API and the React.js frontend
I recommend using REST API or Graphql, then consume the APIs from React. The POST, GET, DELETE, etc methods must send X-Token header with the http call. The backend must verify the token, if token is valid, and role has the required privileges, then your backend serves the API.
I have web application which structure is as-
webapi : django web services [NOT REST] no security implemented
frontend : Angular2. authentication implemented via SAML
Database : Mongodb
Can you please suggest best way to secure webapi, as currently anyone can access web services who has server[api] url
It will be big help if you suggest the authentication and authorization flow because I am totally stuck.
Thanks in advance.
Implement an /authentication on your API which accepts Basic authentication. Make sure you do that over HTTPS. Username and password will be collected by your Angular app and sent back to /authentication. If the user authenticates, return a session token, for example JWT (check pyjwt).
All the following communications between the front and back should contain the token, which is issued only if the user authenticated. The token is inclued in the request headers and specifically in Authororization header using the Bearer schema:
Authorization: Bearer <token>
A JWT contains the username so you can use that on each future request. Furthermore, you are not required to keep record of the issued JWT since each one is self-contained and can have predetermined expiration data.
I've been doing this Java backend for an iPhone app (Jersey REST mainly) and implemented some web services like sign up and log in. Obviously I've needed params like username and pin. Since this services change state in the DB I've made them as POST and I've used #FormParams Jersey annotation for the params. The guy who worked on client kept sending the username and pin in the headers and it took a little while to discover where's the problem.
is this the standard, to put authentication-like data in headers? How do you do it?
if you use the standard http authentication mechanisms like Basic Authentication
then the credentials are sent in the http header
Something like this
POST /private/index.html HTTP/1.1
Host: localhost
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
if you planning to expose this backend through an unsecure network, i would advise you to use https - as it encrpts your header
But if you are implementing your own authentication mechanism - then you can pass the credentials anywhere you like (header or body), that way- your backend would know where to look for the username and password.
check these links for reference
Basic authentication
http authentication