There is something confusing about MobileFirst adapters which is the Cookie policy. Actually I can't find any documentation specifying the detailed use of each kind Cookie policy and how is it related to connectAs attribute.
I have this concern because each time I have to authenticate to a third party application, I get in many troubles while maintaining Cookies and third party session.
Is there someone who could explain it in details please ?
As mentioned in the user documentation for the connectionPolicy element of a HTTP adapter, you are expected to read about each cookiePolicy in its specific RFC - because these cookie policies aren't IBM's. They are industry standards:
https://www.ietf.org/rfc/rfc2109.txt
https://www.ietf.org/rfc/rfc2965.txt
http://hc.apache.org/httpclient-3.x/cookies.html
See also here: What does the cookiePolicy adapter parameter do in Worklight 6.1+?
These cookies don't affect the JSESSIONID cookie returned by the
application server to the client (mobile app). The policy relates to
all the cookies returned by the backend server to Worklight, including
JSESSIONID.
The cookiePolicy does not have a direct relation to the connectAs attribute. Because this attribute will basically dictate if there is a single HttpClient for all sessions, or an HttpClient for each session.
In either case the cookie policy is applied to the adapter.
From the same question:
... each adapter has a separate instance of an HttpClient, and so the
cookiePolicy acts only within the scope of one adapter. Different
adapters will not share cookies by configuration.
About connectAs in greater detail: What does connectAs="endUser" actually do?
Related
We are using the ITfoxtec.Identity.Saml2 library to authenticate with our SSO
service.
The problem is we are using this on a load balanced servers. If we turn sticky sessions off, the application no longer functions.
I've tried setting isPersistent= true when we create the session but it has had no affect. I've seen similar issues posted related to storing SAML state across a web farm with suggestions ranging from:
Changing the configuration so all servers on the webfarm use the same machine key
Creating what amounts to a state service to store authentication.
I would think there would be a way to natively store user state in a cookie that would be reusable regardless if load balancing is being used or not.
Any suggestions on how to attack this?
Using ITfoxtec.Identity.Saml2.Mvc and ASP.NET MVC the isPersitent is a parameter on the CreateSession method. The CreateSession method used in the
ASP.NET sample application.
The method is called after the SAML 2.0 response is accepted to create the user identity cookie handled by the SessionAuthenticationModule.
Default the user identity cookies is not persistent. Setting the isPersitent=true result in creating persistent user identity cookies. The isPersitent setting has nothing to do with load balancing.
It should be possible to support load balancing by setting the isReferenceMode=true. Reference mode change the user identity cookies from being self contained to being a pointer.
In reference mode, a simple artifact is produced during serialization and the token material is stored in the token cache that is associated with the token handler. The token cache is an instance of a class that derives from SessionSecurityTokenCache. For Web Farm scenarios, the token cache must operate across all nodes in the farm.
Maybe you need to implement a token cache.
Updated:
I am sorry to say that I do not have an example. I have instead added some links that may be can be help full.
WIF and Web Farms
About SessionAuthenticationModule IsReferenceMode
SessionSecurityTokenCache Class
I want to provide access control at the Orion Context Broker NGSI API level to ensure real data isolation. I want to make sure that a tenant can only query/update their contexts and NOT those of another tenant.
To do so, I started putting an instance of Wilma PEP Proxy in front of Orion Context Broker. Then I configured my own Identity Manager keyrock GE instance based on official IdM Keyrock docker image and my own Authorization PDP GE based on official AuthzForce docker image.
After a few days of configurations and many tries, finally I could have these three security Generic Enablers working fine, authenticating and authorizing requests for the Orion Context Broker NGSI API using PEP Proxy level 2.
However, level 2 of authorization is not enough to ensure what I want, because service (tenant) and sub service (application path) information are in the headers of the request. Particularly in Fiware-Service and Fiware-ServicePath headers. In order to build header-based authorization policies you need to use level 3: XACML authorization.
The problem is that I made some digging in official documentation of Fiware and I could not find any example of an XACML policy. Besides official documentation of Wilma PEP Proxy (see here) says that you may have to modify PEP Proxy source code in order to get this level of authorization.
As this case is thought to check advanced parameters of the request such us the body or custom headers, it depends on the specific use case. So the programmer should modify the PEP Proxy source code in order to include the specific requirements.
It it's that possible?
Do I really have to modify the PEP Proxy source code to achieve something as simple as a tenant can only access his data?
very good question. There are alternative GEis that support perfectly the use cases you are referring to. Please check this presentation
https://es.slideshare.net/FI-WARE/building-your-own-iot-platform-using-fiware-geis
thanks, best
The Worklight documentation refers to an attribute within the element of an adapter's XML file called connectAs="endUser". It says that this means that:
The connection to the back end is created with the user’s identity.
Only valid if a user realm has been identified in the security tests
for this procedure.
However, what does this actually mean in terms of the HTTP connection that is performed from the adapter to the back-end HTTP server? How does it affect, for example, the JSESSIONID?
EDIT: Further to my original post, Anton Aleksandrov has provided a blog post with more details on how this mechanism works:
https://www.ibm.com/developerworks/community/blogs/worklight/entry/configuring_http_adapters_for_stateless_stateful_backend_connectivity_and_user_identity_propagation?lang=en
What this actually means is that the Worklight server will behave as if it were an "end user" (specifically, a web browser).
Within a given Worklight adapter, the connectAs="endUser" parameter will result in the HTTP Set-Cookie headers being stored as part of an authenticated Worklight session. Subsequent requests that request connectAs="endUser" will send any cookies that are stored as part of that "endUser" server-side session.
The Worklight documentation specifically states that it is only valid in a realm has been identified since if there is no realm, it is not possible to save those cookies for later use in the server-side session.
The effect from a Worklight client app point of view should not change if you choose to use this parameter.
The Worklight server to back end HTTP services will change. Essentially the back end server will treat a Worklight adapter that uses connectAs="endUser" as a single HTTP web browser. So for the example of JSESSIONID:
You initiate a procedure "login" for the first time that specifies connectAs="endUser". This procedure also has an associated security test which enforces a user to be logged into a realm (by whatever means, or anonymous - it doesn't really matter so long as Worklight has a user session to attach cookies to)
When this request reaches a Java-based server that tracks sessions by JSESSIONID, it will detect that this is a first-time request. It will process the request, and send a HTTP response, with whatever content is necessary in the HTTP body. In the HTTP headers, there will be a Set-Cookie response that contains a JSESSIONID.
By virtue of the Worklight procedure having contained connectAs="endUser", the Worklight server will process these Set-Cookie headers and store them alongside the session of the user authorised against the Worklight realm (this is why you need to have a realm that is logged in for this to work)
On a subsequent request to a procedure "mySecondServerProcedure", which also has connectAs="endUser" and the same realm specified, the Worklight server will automatically provide the stored cookies to the server on the outgoing HTTP request, in addition to any you add as parameters on a requestHttp() call in your adapter. In this example, the JSESSIONID that was set as part of "login" will be provided.
If you make another request to a procedure "myThirdServerProcedure" that does NOT have connectAs="endUser" set, no cookies will be provided to the server on the outgoing HTTP response that you do not provide manually as part of the "Cookies" parameters on the requestHttp() call in your adapter.
Important points to note:
A user must be logged in for this to work so that Worklight can associate the HTTP cookies with a session
The session cookie storage is only valid WITHIN the adapter that made the initial request; if you run a connectAs="endUser" request from another adapter after having gotten your JSESSIONID set as part of "login" above, this request will NOT have the JSESSIONID cookie automatically appended to the outgoing request.
If you log out of the authenticated Worklight user session, all reference to these cookies will be gone.
My general rule of thumb is as follows:
If you are doing some fairly simple authentication that requires cookies on the back-end server to remain consistent, use endUser
If you're doing something more complex, or potentially requiring the cookies sent by the server to be available from multiple adapters, find another way to store the cookies. A pattern I like is to have a wrapper method present that makes the outgoing HTTP request and processes the headers that come back in the response to store necessary "global" properties somewhere. In the Worklight world, this can either be as part of a Worklight user session object, or you can call out to an underlying Java or database storage implementation.
The Worklight 6.1 InfoCenter refers to a cookiePolicy parameter which can be set on an HTTP adapter. It mentions four possible values, but doesn't go into details about what they do. Is it safe to assume they all preserve cookies they are returned from the back-end HTTP service? How does that relate (if at all) to the JSESSIONID cookie that may be shared between the Worklight server and any back-end server? Do all calls from that adapter share the same cookie state, or does it depend on the security realm being used?
The cookiePolicy parameter in a HTTP adapter defines the way the adapter's HTTP client handles the cookies returned by the backend.
These cookies don't affect the JSESSIONID cookie returned by the application server to the client (mobile app).
The policy relates to all the cookies returned by the backend server to Worklight, including JSESSIONID.
To read more about each option, refer to the relevant IETF documentation for the specific standard.
To answer (one of) my own questions, I have confirmed that in Worklight 6.2, each adapter has a separate instance of an HttpClient, and so the cookiePolicy acts only within the scope of one adapter. Different adapters will not share cookies by configuration.
I want to create a flexible API Rest server. I will allow the clients to authenticate using HTTP or an APIKEY.
My question is: what is the correct way to add the apikey to a GET request? My problem is the apikey pollutes the url.
I imagine something like this : /book/1/apikey/s4cr4t !
In my opinion you should only use the Authorization header. That's what it is there for.
Putting it in the URL is a bad idea because:
a) as you said it pollutes the URL
b) if you decide to go SSL for security then the API will still appear in log files
c) caches will end up creating multiple copies of the same representation, one for each api key.
For more information on creating your own Authorization scheme go here.
Credentials may be passed using the Authorization header:
GET http://domain.com:/book/1
Authorization: apikey="s4cr4t"
It all depends on how far you want to go but the mechanics stays the same:
Context
The goal is to identify the client with some level of security. (Note: Security is another detailed discussion). Remember that one if the “features” of REST is to be stateless: That means no session state on the server except for resources. To keep the client stateless, it needs to supply on each request enough information that the request is independent. It must give the server a way to identify the client such as a username/password, API Key or token.
You have various options to do this so here are some:
Add HTTP headers to identify the client
Here one can use the Authorization header and send it with each request. There are various authentication schemes but stick to the standard ones such as Basic Auth. Here you would probably stick to SSL. The authentication process generates a kind of token if you like.
You can also make use of a cookie. The cookie must contain no information except that it is a “pointer or key” to a stateful session resource on your server (note: session it a resource which is “rest-legal”). You can create this resource by doing a PUT (+info) with response 200 OK or POST (+info) with a response of 201 Created and Location: /sessions/123334. The session can then be validated by the server such as timeout, valid client ip address, api key etc.
With the method above, you can also define a customer header such as Api-Key: XXXX. But then you limit yourself to special client. Set-Cookie are “well known” headers so browser will handle them kind of transparently. The authentication process can then be done by following links and filling in forms (PUT + POST) to authenticate (create session resource).
Encode an identifier in the content
Here you are free to do what you want too. Just add a field/token/id to your content and let the server verify it.
A RESTful API does application flow by resolving links. See also HATEOAS and Fielding's words. This also applies when you have a separate process of logging in to the application.
Do not encode any data in the URIs. (Out of band information)