Django oauth toolkit not work with apache - django

I use django restframework & django-oauth-toolkit
I test my code on localhost ,the api works well
This is the response header:
Allow → GET, POST, HEAD, OPTIONS
Content-Type → application/json
Date → Wed, 11 Nov 2015 09:41:50 GMT
Server → WSGIServer/0.1 Python/2.7.10
Vary → Accept, Authorization, Cookie
X-Frame-Options → SAMEORIGIN
But I put the project on virtual machine with apache
The oauth not work. I use the right token ,but got 401 UNAUTHORIZED
{
"detail": "Authentication credentials were not provided."
}
This is the response header:
Allow → GET, POST, HEAD, OPTIONS
Connection → Keep-Alive
Content-Length → 58
Content-Type → application/json
Date → Wed, 11 Nov 2015 09:40:37 GMT
Keep-Alive → timeout=5, max=100
Server → Apache/2.4.6 (CentOS) mod_wsgi/3.4 Python/2.7.5
Vary → Accept,Authorization
WWW-Authenticate → Bearer realm="api"
X-Frame-Options → SAMEORIGIN
Why would this happen???
Please guide me
settings.py
OAUTH2_PROVIDER = {
'SCOPES': {'read': 'Read scope', 'write': 'Write scope', 'groups': 'Access to your groups'},
}
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'oauth2_provider.backends.OAuth2Backend',
)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'oauth2_provider.ext.rest_framework.OAuth2Authentication',
)
}

If you are using mod_wsgi, you probably need to add somewhere:
WSGIPassAuthorization On
In AWS elasticbeanstalk a dirty way of patching apache's config is adding this command to your .ebextensions/your-environemnt.conf:
commands:
00_WSGIPassAuthorization:
command: sed -i.bak '/WSGIScriptAlias/ aWSGIPassAuthorization On' config.py
cwd: /opt/elasticbeanstalk/hooks
dirty because it adds one line every time you reload the server.
related Authorization Credentials Stripped --- django, elastic beanstalk, oauth

Related

Why the APIMCLI import process give me 403 Forbidden?

I am getting "403" forbidden when I try to import an API for my distributed APIM instance.
I have 4 VMs running centos 7 and JDK 8:
1st - PostgreSQL
2nd - WSO2 IS with Key manager
3rd - WSO2 APIMMANAGER (2 instances - APIMStore and APIMPublisher)
4th - WSO2 APIMWORKER (2 instances - APIMGateway and APIMTrafficManager)
1- After start all servers OK, I create an 'env' for APIMCLI as follows:
apimcli add-env -n apimm_hml --registration https://apimmanager:9444/client-registration/v0.14/register --apim https://apimmanager:9444 --token https://apimmanager:8244/token --import-export https://apimmanager:9444/api-import-export-2.6.0-v2 --admin https://apimmanager:9444/api/am/admin/v0.14 --api_list https://apimmanager:9444/api/am/publisher/v0.14/apis --app_list https://apimmanager:9444/api/am/store/v0.14/applications
2- I had add my exported APIs to $ .wso2apimcli/esported/apis
3- I get Ok the Tokken from APIM
curl -X POST -c cookies http://apimmanager:9764/publisher/site/blocks/user/login/ajax/login.jag -d 'action=login&username=admin&password=admin' -k -v
* About to connect() to apimmanager port 9764 (#0)
* Trying 10.61.1.68...
* Connected to apimmanager (10.61.1.68) port 9764 (#0)
> POST /publisher/site/blocks/user/login/ajax/login.jag HTTP/1.1
> User-Agent: curl/7.29.0
> Host: apimmanager:9764
> Accept: */*
> Content-Length: 42
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 42 out of 42 bytes
< HTTP/1.1 200 OK
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-store, no-cache, must-revalidate, private
* Added cookie JSESSIONID="E97A1EC2A610C0985E9149C6AEDB0FC9AAF492239437DB11D6A64F0ADBB3CA2424437A19ED8A51409F453D1E53640A547E186AC3810235AD7761DE58093C432314B3D46DE5B353562FBCFEB3268A6084945840CD1083330A69B8564068B92A39B17714D2F94807129392AB6EDFE10CB19EC4ED87E514B31E09D19991F6D6938A" for domain apimmanager, path /publisher, expire 0
< Set-Cookie: JSESSIONID=E97A1EC2A610C0985E9149C6AEDB0FC9AAF492239437DB11D6A64F0ADBB3CA2424437A19ED8A51409F453D1E53640A547E186AC3810235AD7761DE58093C432314B3D46DE5B353562FBCFEB3268A6084945840CD1083330A69B8564068B92A39B17714D2F94807129392AB6EDFE10CB19EC4ED87E514B31E09D19991F6D6938A; Path=/publisher; HttpOnly
< Content-Type: application/json;charset=UTF-8
< Content-Length: 17
< Date: Mon, 21 Oct 2019 14:32:47 GMT
< Server: WSO2 Carbon Server
<
* Connection #0 to host apimmanager left intact
{"error" : false}
4- I get 403 forbiden afte try to import an API:
apimcli import-api -f APIM_ABC_v1.0.zip -e apimm_hml -u admin -p admin -k --preserve-provider=false --verbose
[INFO]: Insecure: true
[INFO]: import-api called
[INFO]: Environment: 'apimm_hml'
[INFO]: Import URL: https://apimmanager:9444/api-import-export-2.6.0-v2/import-api?preserveProvider=false
[INFO]: Source Environment: ConsentimentoService_v1.0.zip
ZipFilePath: /home/centos/.wso2apimcli/exported/apis/ConsentimentoService_v1.0.zip
Error importing API.
Status: 403 Forbidden
Error importing API
[ERROR]: 403 Forbidden
From APIMPublisher Log file I get:
WARN {org.owasp.csrfguard.log.JavaLogger} - potential cross-site request forgery (CSRF) attack thwarted (user:<anonymous>, ip:10.61.1.68, method:POST, uri:/api-import-export-2.6.0-v2/import-api, error:required token is missing from the request) {org.owasp.csrfguard.log.JavaLogger}
After the creation of the environment (ie step 1) try to login to the environment using the below command
apimcli login <environment> -u <username> -p <password>
in your case..
apimcli login apimm_hml -u admin -p admin -k

Browser makes OPTIONS request to django for CORS request, but no POST

I'm trying to submit a form from a react application, via post, to a django server on a different origin.
The browser sends an OPTIONS request, which the cors middleware on the server responds to with a 200, and the following information:
HTTP/1.1 200 OK
Date: Mon, 08 Apr 2019 16:34:38 GMT
Server: WSGIServer/0.2 CPython/3.7.2
Content-Type: text/html; charset=utf-8
Content-Length: 0
Vary: Origin
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with
Access-Control-Allow-Methods: DELETE, GET, OPTIONS, PATCH, POST, PUT
Access-Control-Max-Age: 86400
Connection: keep-alive
But the browser never subsequently makes a POST request. It shows no errors in the console...
Try to install django-cors-headers (https://pypi.org/project/django-cors-headers/) app and just add CORS_ORIGIN_ALLOW_ALL = True to you django settings file. It is the simplest way to fix you issue and this app gives you a lot of CORS customization options.
Or you can write custom middleware and add CORS headers for each response.
Otherwise you could add CORS headers config to you web-server (nginx, apache, etc.).
go to inspect element for request response, and check if any "headers are not allowed" message there.
If so, add that header to CORS_ALLOW_HEADER = ['that-header'] in django settings.py
In my case, cache-control header was not allowed. So I added it, it worked.
It turns out you have to add Cache-Control to CORS_ALLOW_HEADERS to get it to work correctly. Some browsers don't handle setting it to '*'. Here's my setup:
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
]
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
"cache-control",
"pragma",
]

only OPTIONS request is sent with a 200 response

My situation is a bit similar to this question but it differs a bit nor there is an answer.
My backend is python and front-end is Angular. Live sever is Ngnix/Unix while dev is Windows. Every request just sends OPTIONS request, with successful response of 200 but then GET/POST are not followed. It was working perfectly fine and only on production sever is it not working. There are no CORS errors in the console and backend is debug= True for checking purposes but not problems so far cos obviously no get/post is being made.
On development machine, all is working. Previous team had added a custom header 'language':
const clonedRequest = req.clone({ headers: req.headers.set('Language', lang) });
which I noticed is never sent when connected to the live one. In the development setup, I see the following headers:
Accept application/json
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Content-Length 21
Content-Type application/json
Host 127.0.0.1:9000
Language en
Origin http://localhost:4800
Referer http://localhost:4800/start/forgot-pwd
When connecting to the production from front end (Development or in production), the Language header is not being sent but I doubt it has issues. Regardless, my CORS on the backend looks like this:
CORS_ALLOW_HEADERS = (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'language',
'x-requested-with',
)
You need to whitelist specific origins.
Using corsheaders such as:
CORS_ORIGIN_WHITELIST = [
'localhost:4800',
'127.0.0.1:4800'
]
You also need to add to you middlewares right after SecurityMiddleware
'corsheaders.middleware.CorsMiddleware',
And you also need to add 'corsheaders', to you INSTALLED_APPS.
Furthermore, you can simply have CORS_ALLOW_CREDENTIALS = True set and in addition to what I listed above to have CORS working.

cookies not being sent over the server

I have a backbone app (residing on mywebsite.proj.io) that takes code sends it to the django server (authorization.proj.io) that exchanges the code for an access token (simple oauth exchange). I am using Chrome/49.0.2623.87.
The authorization.proj.io sends a cookie back to the client (mywebsite.proj.io) during the auth stage, but this cookie never gets sent back again on future requests. I do not think it is a cross domain cookie issue or a browser unable to set a cookie on a 302 redirect.
I would like to know why the cookie is not be sent to the server on subsequent requests.
Here are some details:
Step 1: Request Header.. Authentication Phase Request: Sending the Oauth 'code' from mywebsite.proj.io to the authorization.proj.io to get the access token. This request is through ajax. The cookie you see here may be from a previous request, but do not care at this point really
GET /fbauth/?code=fb_code_long_string&state=%7B%22client_id%22%3A34343642979%2C%22network%22%3A%22facebook%22%2
Host: authorization.proj.io
Referer: http://mywebsite.proj.io/contribute/?code=fb_code_long_string&state=%7B%22client_id%22%3A34343642979%2C%22network%22%3
Cookie: csrftoken=1MTginTGXLHAku5LMHAMLLTrQEX2M4jj; sessionid=igc8a7vidgbi8rzxgm7whgb5rh8uqxa9`
Step 2: Response Header.. Authentication Phase Response [authorization.proj.io responds with 302 and gets redirected to mywebsite.proj.io and sets cookie]
HTTP/1.0 302 FOUND
Server: WSGIServer/0.1 Python/2.7.10
Vary: Cookie
X-Frame-Options: SAMEORIGIN
Location: http://mywebsite.proj.io/contribute/#access_token=CAAE
Set-Cookie: csrftoken=g0BEHLD0HAH4vBQLQFpKOEn2andrYMhG; expires=Tue, 14-Mar-2017 22:00:16 GMT; Max-Age=31449600; Path=/
Set-Cookie: sessionid=igc8a7vidgbi8rzxgm7whgb5rh8uqxa9; expires=Tue, 29-Mar-2016 22:00:16 GMT; httponly; Max-Age=1209600; Path=/
Step 3: Later, js from mywebsite.proj.io sends a requests to authorization.proj.io.. No cookie is sent
GET /posts/gcc-speaker-training-on-april-25 HTTP/1.1
Host: authorization.proj.io
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://mywebsite.proj.io
Authorization: Basic facebook:CAAEdTwh7fCMBAMEr6wC3ajZANVnZBMPenjseiNShjcXOJJ0PbiJ0GFXI7lSjzkP
DNT: 1
Referer: http://mywebsite.proj.io/contribute/
There were a few things I had to do to get this working.
It turns out that I was doing cross domain requests, and here is how I solved it:
1 : Ensure the server serving your pages has the Access-Control-Allow-Origin set.. I was using the http-server and did the following:
`http-server . --cors`
2 : I did the following for the ajax call
$.ajax('http://authorization.proj.io', {
type: "GET",
contentType: "application/json; charset=utf-8",
success: function(data, status, xhr) {
// do something;
},
error: function(jqxhr, textStatus, errorThrown) {
console.log("cannot get orgs");
},
xhrFields: {
withCredentials: true
},
crossDomain: true
});
Note the xhrFields and crossDomain.
3: I did the following in django settings.py:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
'mywebsite.ngrok.io',
'authorization.proj.io'
)
SESSION_COOKIE_DOMAIN=".proj.com"
I think the last bit was important so that the browser can send the cookie.. So perhaps not cross domain, but cross sub-domain.

Getting "Domain cannot use apis" when using Google Admin SDK Directory API

I'm trying to use the Admin SDK Directory API, specifically to retrieve user info as detailed by the Users: get endpoint.
I have requested the following permissions when oauthing
https://www.googleapis.com/auth/admin.directory.user
https://www.googleapis.com/auth/admin.directory.user.readonly
However, when I make the request to get info on a particular user, I get the following response:
HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=UTF-8
Date: Fri, 26 Jul 2013 18:25:29 GMT
Expires: Fri, 26 Jul 2013 18:25:29 GMT
Cache-Control: private, max-age=0
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Transfer-Encoding: chunked
{
"error": {
"errors": [
{
"domain": "global",
"reason": "domainCannotUseApis",
"message": "Domain cannot use apis."
}
],
"code": 403,
"message": "Domain cannot use apis."
}
}
I have enabled the Admin SDK in the API Console.
I have tried this on a Google Apps Standard (Free) Edition and also a Google Apps for Nonprofits Edition and get the same error. Does the Admin SDK Directory API require a Google Apps for Business Account?
You need to enable the administrative APIs in the G Suite Control Panel.
I am confused. Does it mean that if our App is listed in the Google Apps Marketplace, domains who install our App still have to manually enable the administrative API?