how to get clientContextId from Rest backend in javascript c

Posted by Akioma on 27-Jun-2015 04:50

Hi all,

I have a browser based app using javascript and a Webspeed backend (11.4).
In the webspeed backend we establish a sessionId which is stored in the DB an reestablished for each client call.

Now I have an additional connection to a REST backend for accessing BusinessEntities through a generic Rest Service Interface using the JSDO in the javascript client.
This works fine, and I have managed to setup form-oerealm security in the backend to use our application security.
To synchronise this session with the webspeed session I want to use the progress.session.clientContextId and pass it to our webspeed broker. 

The problem is: The progress.session.clientContextId is always null in the brower, although the connection is made.
In the ABL Session when I access  SESSION:CURRENT-REQUEST-INFO:ClientContextId it correctly shows me an Id for each connected client. 

I assume that I have to set some additional properties in the spring settings, but have not idea where to start...
any help greatly appreciated!

thanks,

Mike

All Replies

Posted by egarcia on 28-Jun-2015 05:17

Hello,

Just to clarify, to access the clientContextId, you would write "session.clientContextId" where session is your variable of type progress.data.Session or progress.data.JSDOSession. (In your post you mentioned progress.data.clientContextId which is not defined.)

Since you mention that the value is null (not undefined), it looks like you are accessing the right property.

The clientContextId property is set from the value in the X-CLIENT-CONTEXT-ID HTTP header (found in the HTTP response).

You can use the steps in the following link to enable SSO for Web applications:

   documentation.progress.com/.../index.html

Please notice that the documentation and the .xml file have "headername" value="X-OE-CLIENT-CONTEXT-ID".

Please change it to X-CLIENT-CONTEXT-ID because that is the value that the code for the Session/JSDOSession expects.

Related link:

documentation.progress.com/.../index.html

I hope  this helps.

Posted by Akioma on 28-Jun-2015 09:17

Hi,

thanks for your help.

yes, I am using the clientContextId from my session variable.

Looking into setting the SSO parameters I realised that they are also available for the basic-oerealm authentication.

Does that mean I do not need form authentication in order to establish session context handling?

Mike

Posted by Akioma on 29-Jun-2015 04:28

ok, tried with basic-oerealm authentication and the authentication through my HybridRealm seems to work.

But then the progress session tries to call "/static/home.html" which fails with a 404.

From reading throgh the documentaton I understand that this is the default value for the login-target parameter, but I do not understand what this is needed for, or how I can (must?) use it / deactivate it.

All I want is to authorize through my HybridRealm and get a sessionId...

Do I have to provide this login-target? And if so, how do I implement it?

Any help greatly appreciated!

Mike

Posted by Shelley Chase on 29-Jun-2015 09:25

Hi Mike,

It is used to contact the server before a login attempt. You can ignore the 404 error - it does not cause any problem.

If you created the service through a PDSOE project, the file should be there. If it is not you can create a file home.html in the static directory of your webapp. The content could simply be:

<html>
<body>
Home
</body>
</html>

Thanks

-Shelley

Posted by whenshaw on 29-Jun-2015 09:37

Hi Mike,

The Session's login logic is to make a request for a specific, protected, resource from the Web application that will cause the server-side authentication process to authenticate that request. By default, the Session requests <serviceURI>/static/home.html (where serviceURI is the first parameter to login() ). Web applications produced by PDSOE include this file by default. If your Web application doesn't have one, you can just add it. The default file that PDSOE uses is simply:

<html>

<body>

Home

</body>

</html>

You can also specify a different resource by using the 4th parameter of Session.login(). Whatever you use, if you want the login to actually authenticate the user, you need to make sure that the Web application's security XML file (for example, oeablSecurity-basic-oerealm.xml, on the doc page that Edsel sent the link to) specifies that it is a protected resource.

--Wayne

Posted by Akioma on 29-Jun-2015 09:37

Hi Shelley,

the file is there. The problem is that I get a LOGIN_GENERAL_FAILURE .

I was assuming that this is due to the 404, but if I understand you correct there must be some other reason for this...?

Thanks,

Mike

Posted by whenshaw on 29-Jun-2015 09:39

Can you use an HTTP monitor (the Network tab in a browser debugger, or Fiddler, or something similar) to see what the actual request is?

Posted by Akioma on 29-Jun-2015 10:39

figured out what the problem was: I did not return a value for the ATTR_ENABLED attribute.

Now the login works without error, BUT: I still get no clientContextId. Also in the backend when I display SESSION:CURRENT-REQUEST-INFO:ClientContextId it is empty.

I set OEPreauthfilter:

  <b:bean id="OEPreauthfilter" class="com.progress.rest.security.OERequestHeaderAuthenticationFilter">

         <!-- USER-EDIT: To turn on SSO :

              1. Set "enabled" property to true

              2. For single-domain supply the Domain Access Code as the value for "key" property

              3. For multi-domain supply the absolute path of a 'registryFile' generated using OpenEdge's  

                 $DLC/bin/gendomreg.bat utility as "registryFile" property -->

          <b:property name="enabled" value="true"/>

          <b:property name="key" value="123456"/>    

          <b:property name="registryFile" value= "" />

          <b:property name="encoding" value="OECP"/>

          <b:property name="headername" value="X-CLIENT-CONTEXT-ID"/>  

          <b:property name="authenticationManager" ref="authenticationManager" />

   </b:bean>

Anything I am missing here...?

Posted by Akioma on 29-Jun-2015 15:01

Hi Wayne,

Hier exactly Do I Specify that a resource is protected?

Thanks,

Mike

Posted by whenshaw on 29-Jun-2015 16:09

If you are using one of the Spring Security templates (for example, oeablSecurity-basic-oerealm.xml), it is already set up for /static/home.html and you can use it as a model (search on "/static/home.html" -- be aware there's another home.html in there that is not the same one, it has a different path). You mentioned that your login is working now -- try it with invalid credentials and if the login fails, /static/home.html is protected. I will try to find some more specific information that may be able to help you.

Posted by knavneet on 30-Jun-2015 01:59

Hello Mike,
 
I believe you don’t need to configure OEPreauthfilter unless you expect the Mobile webapp to receive a pre-authenticated SSO token from an external authentication system like Rollbase. The pre-auth filter is currently supported for Rollbase Single-Sign-On to access OpenEdge Service Object. If this is not your configuration requirement, you can skip this filter.
There is a CCID support in the security template, which I think you might want to look at.
 
Sometimes COOKIEs are not allowed in some clients and REST JSON data services do not perform URL rewriting of session-ids. In these cases the client must have some means of obtaining the user's login session id. This is performed using the CCID functionality available to other AppServer clients. The CCID support inserts a X-CLIENT-CONTEXT-ID http header in each response message. The client may obtain the value and insert it into the next request's URL as a "JSESSIONID" query option. To enable CCID response headers add the "ccid" property to the "OEClientPrincipalFilter" bean configuration.
 
Property Name
Description
Datatype
Default
Range
"ccid"
Enable/disable CCID
Boolean
"true"
{"true"|"false"}
 
I believe you need to find “OEClientPrincipalFilter” and configure “ccid”
 
Also, regarding your question about URL access privilege, in the xml file you will find Intercept URL like this:
===
   <!-- Restricted Mobile session class uses this page as part of its
             login() operation, protect it so it triggers user
             authentication -->
        <intercept-url pattern="/static/home.html"
                    access="hasAnyRole('ROLE_PSCUser')"/>
===
 
This means that access to "/static/home.html" resource is available to anyone with role PSCUser. You can change the access permission as per your requirement.
(Note that Spring appends ROLE_ as a prefix, so if you use OE Realm to return roles for a user, make sure you do it without ROLE_ prefix, i.e. PSCUser and not ROLE_PSCUser).
 
Please excuse me if I didn’t understand the configuration and requirement correctly.
 
If you can let me know the appSecurity file you are using and the filters or beans that you configure, I can try to look into what might be missing.
 
Thanks,
Navneet
 
[collapse]
From: Akioma [mailto:bounce-Akioma@community.progress.com]
Sent: Monday, June 29, 2015 9:10 PM
To: TU.Mobile@community.progress.com
Subject: RE: [Technical Users - Mobile] how to get clientContextId from Rest backend in javascript client
 
Reply by Akioma

figured out what the problem was: I did not return a value for the ATTR_ENABLED attribute.

Now the login works without error, BUT: I still get no clientContextId. Also in the backend when I display SESSION:CURRENT-REQUEST-INFO:ClientContextId it is empty.

I set OEPreauthfilter:

  <b:bean id="OEPreauthfilter" class="com.progress.rest.security.OERequestHeaderAuthenticationFilter">

         <!-- USER-EDIT: To turn on SSO :

              1. Set "enabled" property to true

              2. For single-domain supply the Domain Access Code as the value for "key" property

              3. For multi-domain supply the absolute path of a 'registryFile' generated using OpenEdge's  

                 $DLC/bin/gendomreg.bat utility as "registryFile" property -->

          <b:property name="enabled" value="true"/>

          <b:property name="key" value="123456"/>    

          <b:property name="registryFile" value= "" />

          <b:property name="encoding" value="OECP"/>

          <b:property name="headername" value="X-CLIENT-CONTEXT-ID"/>  

          <b:property name="authenticationManager" ref="authenticationManager" />

   </b:bean>

Anything I am missing here...?

Stop receiving emails on this subject.

Flag this post as spam/abuse.

[/collapse]

Posted by Michael Jacobs on 30-Jun-2015 04:35

Hi Mike,

Going back to your original question : how do I synchronize 'sessions' between your Mobile REST services and your WebSpeed application?  I have some additional information that may help.

The Mobile REST services sets the OpenEdge Client Context ID with the value of the HTTP session the Tomcat server assigns when you do a form-login model authentication.    Since this is not configurable - your WebSpeed sessions will have to synchronize with the REST sessions, using the REST service's session-id.   The REST service's are configured to not generate HTTP sessions when you use one of the BASIC authentication models.

When you see a non-zero client context id in the SESSION:CURRENT-REQUEST-INFO:ClientContextID of a request originating in a REST service - it will be the HTTP session-id of the authenticated client as issued by the web server via the Spring Security modules.   The value will be "0" if the REST service's Spring Security is executing one of the basic authentication models.

When you configure the OEClientPrincipalFilter bean's <property name="CCID" value="true"> in the appSecurity-oerealm-form.xml configuration (assuming that is what you configure to obtain actual client sessions), the filter will insert the X-CLIENT-CONTEXT-ID header in a REST request's response - IF an HTTP session was created by the server.   If Spring Security configuration you set in web.xml does not create sessions, no session-id is created, and the header will not be returned.  For example - when you use a basic form model, no HTTP session is create.  You should be able to see this header using a HTTP debug proxy between your browser and the server.

The built-in CORS filter in OpenEdge REST services are configured to allow your java-script client to see the X-CLIENT-CONTEXT-ID header in the response message ( or should be ).   As Edsel and Wayne have indicated, this is also available in the JSDO services, so you can choose the source.   Once your code has the value of the X-CLIENT-CONTEXT-ID header it can send that to WebSpeed so it can record the session and use it.

As Navneet says, do no use the OEPreauthFilter as its purpose lies in another area of REST client support.

Mike J.

Posted by Akioma on 30-Jun-2015 11:59

ok, disabled OEPreAuthFilter and enabled ccid.

But I do not get a clientSessionId. But I am using oerealm-basic-authentication- do I understand correct hat using basic authentication I never get a sessionId? Do I have to use oerealm-form-authentication?

Posted by Michael Jacobs on 30-Jun-2015 13:19

Correct.   Session ids exist for the case where a client performs a form login (authentication) who's lifetime spans multiple HTTP client requests and have a defined logout action - the sesison id is what binds the individual HTTP requests into a single login session.   The HTTP BASIC model of user login (authentication) spans only the lifetime of a single HTTP request and has no defined logout action - therefore no session id is needed or created.

This thread is closed