So, I'm trying to use PHP Http sockets to execute a rest action on a distant server.
My goal is to have my PHP script automatically execute various actions that I usually perform when browsing "manually".
The distant website is an e-commerce oriented portal (no name provided) and connection is through HTTPS (I think that may be the problem here).
[There is no hacking here, just automation!]
I manage to execute several actions with my script like logging in to the website using my username and password, adding items to my cart etc.
Using Firebug I found that the action triggered for confirming order is /createOrder, but when I try to validate my order using my script with my session cookies I get a 401 Unauthorized error (detailed below)
So I tried several times to access this action with CURL using my usual username and password but I never manage to get access.
How is it possible that I could access it by browsing manually but not with my script? Is there a way to make it work?
Response headers include:
Server: Apache
X-Cnection: close
Content-Length: 1518
WWW-Authenticate: Basic realm="WebLogic Server"
X-Powered-By: Servlet/2.5 JSP/2.1t
"The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.46) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity MAY include relevant diagnostic information. HTTP access authentication is explained in section 11."
Problem solved.
It was a cookie issue.
I was not sending the token cookie correctly.
Related
I have already created an api using php slim framework. But I have an issue with securing my api. I want to access only api for the authenticated users only.
I have already added user login to my front end angular project. That is fine. But when the someone directly calls the api endpoint its show the result related to that endpoint.
For example. I have the following endpoint.
slimapi/customers/view
This endpoint shows all the data in the customer's table.
When someone types this URL in the browser. it shows all data related to that api endpoint. but I want to show some customers message when someone tries to access my api endpoint without using front end application.
You can Manage JWT Token
when client sends you login request and if login request and credential matched then you give the client a token. Then After every request, you check the token is it valid then you give the access.
just see the documentation of JWT
https://github.com/tuupola/slim-jwt-auth
You could use the OpenID Connect protocol (based on OAuth 2 and JSON Web Tokens).
But this would maybe an overkill for the most scenarios, because a JWT would only makes sense if you have to scale the "session" over multiple servers and/or load balancers in the back-end infrastructure. Also a simple logout is not possible with JWT based tokens. If you start to manage JWT blacklists on the server-side, the API will not be stateless anymore.
I think a very long API-Token within the HTTP header, e.g. a UUID, would be secure and good enough in the most cases.
The HTTP Authorization request header contains the credentials to authenticate a user agent with a server, usually after the server has responded with a 401 Unauthorized status and the WWW-Authenticate header.
Syntax:
Authorization: <type> <credentials>
Basic Auth
Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l
Token based
Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ
UUID as Token
Authorization: Bearer bb79dfb5-17fd-4ebc-acd5-548e308e5f9a
Also make sure, that all API request are SSL (HTTPS) encrypted.
PS: If you just want secure your API for a web application, a classic Session with Cookies is also good enough and very secure.
I have a php websocket based application where the websocket is the core. Would it be a good idea to use sec-websocket-protocol for authentication.
This is my plan.
User logins using there credentials and I use php sessions to track the user between pages.
Now when user initiates the application a random token is generated and stored in Database which is then passed in the header when websocket is initiated. The header looks kind of
Cache-Control:no-cache
Connection:Upgrade
Host:tonywilk.no-ip.org:12352
Origin:http://********.com:port
Pragma:no-cache
Sec-WebSocket-Key:DMF3ByMTLq+cp7AyMN0qUA==
Sec-WebSocket-Protocol:**Token** **<-- browser sends token
Sec-WebSocket-Version:13
Upgrade:websocket
I use the token to verify the user and send server respons with handshake
Connection:Upgrade
Sec-WebSocket-Accept:L6wqtsHk6dzD+kd9NCYT6Wt7OCU=
Sec-WebSocket-Protocol: **Token** <-- server replies ok
Upgrade:WebSocket
Is this a good idea or is there a better way to do it
You should use Authorization header for authentication.
Using Sec-WebSocket-Protocol header for authentication is bad idea, because it changes the header meaning:
The |Sec-WebSocket-Protocol| header field is used in the WebSocket
opening handshake. It is sent from the client to the server and back
from the server to the client to confirm the subprotocol of the
connection. This enables scripts to both select a subprotocol and be
sure that the server agreed to serve that subprotocol. (c) RFC 6455 – The WebSocket Protocol
I'm using RatchetPHP for my websocket application.
I can't pass headers when opening a websocket connection, so I pass an OAuth2 token to the websocket uri. It looks like this:
new Websocket('ws://localhost:8482?access_token=XXX')
If you can easily retrieve query parameters in your websocket application, this is something you could try.
This is the trick I'm using in Sandstone: https://eole-io.github.io/sandstone/authentication.html
I am writing a webservice client which runs from the command line and accesses a service which uses Oauth2.
I seem to be getting the Oauth token correctly, and the first request to the webservice recognizes the token. However the response is a 303 redirect (I have set CURLOPT_FOLLOWLOCATION => true) however the subsequent page says that I have supplied no authentication token.
Currently I am passing the oauth token by setting a header for the curl handle:
"Authorization: OAuth2 $oauth"
I suspect that the header is not being included in subsequent requests.
I tried setting CURLOPT_UNRESTRICTED_AUTH => true, to no avail (but according to the manual, that persists a username and password across redirects - not the authentication header).
The webservice allows for oauth tokens to be sent in an authentication header or in the URL (but not as a cookie). Setting the token in the URL returns the same redirect (i.e. without the token in the URL) hence I can't use this method with CURLOPT_FOLLOWLOCATION.
(the service does not allow for oauth tokens sent in cookies, PHP version is 5.6)
Having discovered that lots of other bad things are happening on the Websense proxy I was connecting via (caching content known to be expired, caching POST responses!) I tried bypassing it altogether and all the problems vanished.
I'm trying to use the new office365 unified api to query the users list and user file.
I've created the application in azure management portal, and I gave the permission to the new api application (with the directory and files read)
I've created both a client and a webapi application, to try.
In my code, I use a x509 certificate to acquire the token, and I get it without problem.
Then I call, with curl, the url "https://graph.microsoft.com/beta//users/" to get the users list, and I get a 500 error:
Object reference not set to an instance of an object.
I've tried with other urls, and also I've tried call that url, with the same header (the authorization: bearer, etc) directly in firefox, and I've the same problem.
I've checked if it's an authorization error, but it doesn't seam... If I omit the authorization header, or I but a wrong one, I get a 401 error.
Here's the header I'm sending to the url:
User-Agent: php-microsoft-graph-api/1.0
Authorization: Bearer ey...
Accept: application/json
client-request-id: cbe6f962-8b7e-ee4d-a1bc-34c260cf93ec
return-client-request-id: true
I've tried the url with the graphexplorer2 app, and it work ok...
Any hint or suggestion to debug the problem?
Thanks to all
EDIT: I've forgot to say that I'm using the client credential flow (because I'm developing a daemon) and I've notice that the access token that I get, is shorter than a token with the normal authentication flow...
So, a new question: is the new office 365 api compatbile with client credential flow? There's any method I could use to "authenticate" my app, without passing thought a browser?
Client credential flow is not yet supported in the Office 365 unified API preview. It is on the roadmap. In the meantime you can use app + user flows.
I have an application that uses REST API and I'm implementing Digest Authentication for the security scheme. The problem is, when I log into the application, I don't want the default user/pass windows to pop out every time a resource is consumed, but instead I want it to use the username and password that was written when logged in using the app log in form, so how do I do to use that information when the first 401 status response is received?
You should pass the authentication information in the request headers when the request is made against the resource.