I've build a web api service with basic authentication and using a global DelegatingHandler implementation which I hook up to the web API GlobalConfiguration, in order to extract the username:password credentials from the request and hook an IPrincipal to the HttpContext if the credentials map to a valid user.
I've tested my api thoroughly on localhost and it's working fine, but not quite when hosted on IIS on a VPS.
I've hooked up remote debugging on the VPS in order to inspect whats going on and it turns out that whenever I include the authorization header to my request, the breakpoints I have set on the message handler are not getting hit, meaning that the request does not reach the handler. If I remove the Authorization header from the request, the breakpoint is getting hit and the handler is able to process it.
Since the message handlers are the first that will process the request in the pipeline (from what I know of, correct me if I'm wrong) I guess there must be an IIS or setup issue that I'm not aware of that messes the authentication process.
Fiddler Request Headers
GET http://myip/api/v1/route/parameter HTTP/1.1
Content-Type: application/json; charset=utf-8
Authorization: Basic ZHJpdmVyOjEwMTAyMDAz
Host: myip
Fiddler Response Headers
HTTP/1.1 401 Unauthorized
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
WWW-Authenticate: Basic realm="myip"
X-Powered-By: ASP.NET
Date: Mon, 22 Aug 2016 15:04:15 GMT
Content-Length: 61
{"Message":"Authorization has been denied for this request."}
What could be possibly be wrong, where should I look at for a solution?
EDIT
Had to disable Basic Authentication from the Authentication menu on the right pane setting for the IIS application.
Related
According to this document
https://developers.onelogin.com/openid-connect/guides/auth-flow-pkce
Token Endpoint for PCKE flow is None (not Basic or POST)
So, how can I use the validation token API https://developers.onelogin.com/openid-connect/api/validate-session because it supports Basic authentication or POST but not for None (PCKE) I can't find any information relate to this.
NOTE: I have tried to request with Basic authentication and without + client_id, client_secret as a parameter but not working.
response 401 Unauthorized
{
"error": "invalid_client",
"error_description": "client authentication failed"
}
I'm using OIDC with PKCE, and I managed to call the https://openid-connect.onelogin.com/oidc/token/introspection endpoint with a token retrieved via the authorization code flow:
$ curl -i -d "token=...&token_type_hint=access_token&client_id=..." https://openid-connect.onelogin.com/oidc/token/introspection
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Content-Length: 304
Content-Type: application/json; charset=utf-8
Date: Thu, 25 Apr 2019 23:37:42 GMT
Pragma: no-cache
X-Powered-By: Express
Set-Cookie: ol_oidc_canary_040819=false; path=/; domain=.onelogin.com
{"active":true,"sub":"...","client_id":"...","exp":1558819177,"iat":1556227177,"sid":"...","iss":"https://openid-connect.onelogin.com/oidc","jti":"...","scope":"openid profile email"}
Both the access_token and refresh_token returned from the auth code flow https://developers.onelogin.com/openid-connect/api/authorization-code-grant worked, and the access_token only returned {"active":false} after it expired.
Make sure you are not setting the Authorization header, and only set your client_id in the payload.
Use client_id and code_verify in the POST body. That will authenticate the request on that endpoint.
My app is required to support users logged in via SSO on a 3rd party server.
I configured settings.py based on the docs, i.e.
MIDDLEWARE_CLASSES = [
'...',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.PersistentRemoteUserMiddleware',
'...',
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.RemoteUserBackend',
]
I tried to test this using Postman on a couple of the app's URLs with no auth and with basic auth (user is defined) and, of course, with REMOTE_USER (and/or HTTP_REMOTE_USER header set).
In all cases I get a 401 - unauthorized code. Moreover, the breakpoint in authenticate is never called. The process_request in the middleware is called, but the REMOTE_USER header is not in request.META.
What else do I need to configure (in Django, Postman - or better still Apache) so that the REMOTE_USER will be set?
My knowledge of Apache is minimal, so a link to an example will help a lot.
The closest "solution" I saw is this, but it seems that the person circumvented the proper way to do this.
UPDATE
The Postman request is simply to one of the basic services which requires users to be logged in (#login_required decorator in Django)
I've tried with both basic auth and no auth.
The reply is a 401 without additional information.
>curl -i -H 'REMOTE_USER: user' localhost:9000/project/files/
HTTP/1.0 401 Unauthorized
Date: Sun, 17 Dec 2017 13:38:38 GMT
Server: WSGIServer/0.1 Python/2.7.10
Expires: Sun, 17 Dec 2017 13:38:38 GMT
Vary: Cookie
Last-Modified: Sun, 17 Dec 2017 13:38:38 GMT
Location: /accounts/login/?next=/project/files/
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=utf-8
Same command with cURL. The Location seems to suggest it tried to redirect to the login page (which should not happen)
I'm trying to collect and download my lifelog user data. The first step into doing this is getting a user-access token. I am encountering problems while requesting authorization.
From the sony developer authenticization page I am told to input the following code into my API explorer:
https://platform.lifelog.sonymobile.com/oauth/2/authorize?client_id=YOUR_CLIENT_ID&scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read
I am supposed to receive the authorization code as such:
https://YOUR_CALLBACK_URL?code=abcdef
However, this is what the current situation is actually like:
I have replaced my actual client ID below with MY_CLIENT_ID for security reasons
INPUT:
GET /oauth/2/authorize?client_id=MY_CLIENT_ID&scope=lifelog.profile.read%2Blifelog.activities.read%2Blifelog.locations.read HTTP/1.1
Authorization:
Bearer kN2Kj5BThn5ZvBnAAPM-8JU0TlU
Host:
platform.lifelog.sonymobile.com
X-Target-URI:
https://platform.lifelog.sonymobile.com
Connection:
Keep-Alive
RESPONSE:
HTTP/1.1 302 Found
Content-Length:
196
Location:
https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Access-Control-Max-Age:
3628800
X-Amz-Cf-Id:
HILH9w3eOm-6ebs_74ghegYQyWS4xyqA1l0gXPRJuuubsoZ6eiiS3g==
Access-Control-Allow-Methods:
GET, PUT, POST, DELETE
X-Request-Id:
76caccfc976d40259ef30415d10980e9
Connection:
keep-alive
Server:
Apigee Router
X-Cache:
Miss from cloudfront
X-Powered-By:
Express
Access-Control-Allow-Headers:
origin, x-requested-with, accept
Date:
Sun, 22 Jan 2017 03:00:42 GMT
Access-Control-Allow-Origin:
*
Vary:
Accept
Via:
1.1 dc698cd00b7ec82887573cfaba9ecca6.cloudfront.net (CloudFront)
Content-Type:
text/plain; charset=utf-8
Found. Redirecting to https://auth.lifelog.sonymobile.com/oauth/2/authorize?scope=lifelog.profile.read+lifelog.activities.read+lifelog.locations.read&client_id=MY_CLIENT_ID
Nowhere can I see the authorization code in the above code. I even tried copying and pasting the URL (on the last line) into my browser, it says "localhost.com took too long to respond"
This is where I input my request
I am not sure whether it is an issue with the callback URL. I don't have an actual website or app made, I just used the default localhost
I am a beginner in this and would really appreciate all help.
My azure hosted web API uses the O365 Calendar and Mail REST APIs for creating events and mails on behalf of the users. All necessary permissions have been enabled for the corresponding Azure AD application. My question - Accessing the mail API using the Bearer OAuth token as part of the header succeeds but when I use the same token for the events API, it fails with a 403.
The Documentation I have been following for my implementation is the official msdn one and the update - https://social.msdn.microsoft.com/Forums/exchange/en-US/6fc135ae-f8f9-4b4d-b50b-f00a2bd79a30/office-365-rest-api-mail-calendar-contacts-update?forum=exchangesvrdevelopment
Fiddler trace (Raw view of request) -
POST https://outlook.office365.com/ews/OData/Me/Events HTTP/1.1
Accept: application/json
client-request-id: 00000000-0000-0000-0000-000000000000
Authorization: Bearer <OAuth token>
Content-Type: application/json; charset=utf-8
Host: outlook.office365.com
Content-Length: 287
Expect: 100-continue
{"Attendees":[{"EmailAddress":{"Address":"sample#sample.com","Name":null},"Type":"Required"}],"Body":{"Content":"Hello World","ContentType":"HTML"},"End":"2014-10-22T19:00:00Z","Location":{"DisplayName":"Conf Room M"},"Start":"2014-10-22T18:00:00Z","Subject":"Testing"}
Text view of response -
{"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."}}
Fiddler trace of the Mail API request that works fine -
POST https://outlook.office365.com/ews/OData/Me/sendmail HTTP/1.1
Accept: application/json
client-request-id: 00000000-0000-0000-0000-000000000000
Authorization: Bearer <OAuth Token>
Content-Type: application/json; charset=utf-8
Host: outlook.office365.com
Content-Length: 171
Expect: 100-continue
Connection: Keep-Alive
{"Message":{"Body":{"Content":"Test","ContentType":"HTML"},"Subject":"test","ToRecipients":[{"EmailAddress":{"Address":"sample#sample.com","Name":null}}]}}
Considering that you are getting a 403 (Forbidden) error for one API, I'd suggest you review the resources enabled for the application. Can you make sure you have Write permissions for the Calendar API? I know you mentioned that you've done this before, I'm just checking in case of the small chance you missed those Write perms.
Sorry for having kept this question hanging.
The issue was with the ClientSecret (either had stale permissions on it or was wrong in the first place). Generating a new one via the management portal fixed this issue.
I've a DotnetOpenAuth authorization server which works great on my localhost. However after publishing it my refresh access token request is blocked.
The request for a accesstoken, with success
POST https://myurl/identity/oauth/token HTTP/1.1
Authorization: Basic dsjSDLFJKSKLJesww
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: DotNetOpenAuth.Core/4.2.1.13026
Host: myhost
Cache-Control: no-store,no-cache
Pragma: no-cache
Content-Length: 86
Expect: 100-continue
Connection: Keep-Alive
username=theusername&password=fancypassword&scope=somescope&grant_type=password
The refresh request:
POST https://myurl/identity/oauth/token HTTP/1.1
Authorization: Basic dsjSDLFJKSKLJesww
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: DotNetOpenAuth.Core/4.2.1.13026
Host: myhost
Cache-Control: no-store,no-cache
Pragma: no-cache
Content-Length: 272
Expect: 100-continue
refresh_token=_ttH%21IAAAAGiYhlufAaXURH5P2oDOnPYgJx7YhoR33isvZkPPvlyUgQAAAAHoBYyDMLhq1qwGHHH2uGrLoHZli77XHbCnSFJSKLFJ3kl2j3klj2kljKFSJKLSJKL#$k3ljfsklfjl2
And the response:
Technical Information (for support personnel)
Error Code: 403 Forbidden. The server denied the specified Uniform
Resource Locator (URL). Contact the server administrator. (12202)
Any help, guidelines, pointers in any direction, would be very much appriciated!
I changed the url/username/password/scope/base64/refreshtoken for this example.
Their seems to be a setting in the TMG Forefront - Authentication Delegation which blocked the request.
Method used by Forefront TMG to authenticate to the published Web
server:
No delegation, and the client cannot authenticate directly
No delegation, but client may authenticate directly
It was set to option 1 after changing it to 2 the request is no longer blocked!