Using the EntireX .NET wrapper and EntireX Security from a Intranet ASP.NET solution
In the following I present how my company use the EntireX .NET wrapper classes and EntireX Security from a Intranet ASP.net solution.
I hope some of you will review and discuss our setup.
I?ve chosen not to send the actual code, since it?s very easy to get lost in less important details of production code. Instead I try to explain the design behind the code, showing slightly simplified code samples to elaborate.
Our task
It is our task to substitute all 3270-terminal emulation with web based clients. The business logic will be the same as that of today, programmed in Natural/Adabas running on a z/OS.e mainframe. To expose the existing business logic we produce a service layer, that is numerous natural subprograms with no presentation logic. We use the .NET wrapper to create C# classes making the services available from the .NET framework.
See attached gif-file for overview.
Handling authentication & authorizationFor clarity I?ll describe the first call (logon), subsequent calls and the session end (logoff) separately in the following.
The first call
When the user logs on, a service is called to get user rolls. To make this first call we initialize a broker object like this:
Broker b = new Broker(adr,RACFUsername);
b.Token = HttpContext.Current.Session.SessionID;
That is we assign the broker Token property the unique session ID used to identify the IIS-session.
Since we are using EntireX security we must log on to the broker like this:
b.Logon(RACFPassword);
To avoid subsequent logons during a session, the security token of the first broker instance is cached between calls in the IIS session object, like this:
HttpContext.Current.Session.Add(?Securitytoken?,b.SecurityToken);
In our solution EntireX Security & RACF is used for authentication only. Our natural subprograms perform the authorization. For this we need the user name authorized by RACF.
Under certain configuration settings , the variable *USER will contain the user name if we instantiate the service object like this:
Service s = new Service(b, “RPC/SRV1/CALLNAT”);
s.NaturalLogon = true;
s.UserIDAndPassword(b.UserID,“NOPASSWORD”);
Finally, the class exposing the business logic can now be instantiated, for example:
Example e = new Example( s );
and the business methods can be called, like this:
int result = ex.Calculator( “+”, 10, 15);
Subsequent calls
For subsequent calls within a session we do not log on to the broker. Instead the broker SecurityToken is assigned the cached security token, instantiating the broker like this:
Broker b = new Broker(adr,RACFUsername);
b.Token = HttpContext.Current.Session.SessionID;
b.SecurityToken = (byte)HttpContext.Current.Session[?Securitytoken?];
As for the first call we instantiate the service object like this:
Service s = new Service(b, “RPC/SRV1/CALLNAT”);
s.NaturalLogon = true;
s.UserIDAndPassword(b.UserID,“NOPASSWORD”);
And call the business methods like this:
Example e = new Example( s );
int result = ex.Calculator( “+”, 10, 15);
Note: We?ve set the web session timeout lower than the client-none-activity-timeout of the broker, but still we can get situations where the cached security token expire. In this case we force the session to end and the user to log on once again.
Session end (logoff)
When the session ends, either because the user explicitly chooses to log out, or because the session times out, the session object is cleared hereby clearing the cached security token. However just before this happens (in Session_End of the global.asax or a similar method for explicit logoff) we call the broker log off method:
b.Logoff();
Configuration
On the client site EntireX 7.11 patch 30 has been installed. During the installation the EntireX Security option was selected.
On the mainframe site EntireX 7.11 patch 30 has been installed. In addition EntireX Security, at the same level, has been configured and security has been activated by specifying SECURITY=YES in the Broker attribute file.
Due to the fact that all communication is based on the Callnat model, a Callnat server has been established. I addition to the basic Natural parameter setup, the following parameters has been specified:
? SERVER=ON, to activate Callnat
? LOGONRQ=ON, to ensure that calls can?t be accomplished without a proper logon
? SRVUSER=?*NSC?, to ensure that the Callnat server will run under control of a password specification in Natural Security
As explained earlier, it is vital for the basic programming, that the userid of the client is available to the Natural code in the server application. To make this possible, the parameter ?Logon Option? has been set to ?S? in the ?additional options? for the Natural library in use, hereby the userid of the client is transferred to the *USER field on the Natural site. It is our understanding that this will insure that the client site can?t specify an alternative value of the userid, by a possible misuse of a corresponding ?service? call on the client side. Thus ? this will ensure that the correct userid is specified, that it is not manipulated and that the control of the password is based on settings in RACF alone.
Questions
? Is our use of the .NET Wrapper and EntireX Security as described above sound?
? Is it correct that by setting the parameter ?Logon Option? to ?S? in the ?additional options? for the Natural library in use, we insure that the client site can?t specify an alternative value of the userid, by a possible misuse of a corresponding ?service? call on the client side? And that this will ensure that the correct userid is specified, that it is not manipulated and that the control of the password is based on settings in RACF alone?
? What are the strengths and weaknesses of our solution?
? Where could we choose to do otherwise?
? Does the use of Natural Security to get the authenticated username constitute a performance overhead? And if so, how much?
? Is there any secure alternatives to *USER passing the username to the Natural subprograms?
? According to our SAG-consultant, the security token and token should somehow be used in combination by the broker to identify a broker session. To make it harder to use a stolen security token we assign the sessionid to the token. Testing this feature however it seems that the token value is ignored by the broker. Does the token property have any meaning?
? When do we get a overloaded method Service.UserIDAndPassword taking only userid as parameter? The need for a dummy password which can?t be null or the empty string seems unprofessional.
Best regards,
Michael
Thank you for your overview of using EntireX Wrapper from ASP.NET. I will probably reference other customers to it in future as it is clear and understandable!
The logon option “S” is a relatively recent addition to Natural Security. You appear to be using it as intended: it allows a user to be logged on to Natural Security when EntireX Security has already authenticated the userid, similar to using AUTO=ON in CICS or batch with the userid being supplied by SAF (ACF2, RACF, etc). (You could use ServLine24 to enter an Enhancement request for the additional overloaded method).
Token is used to allow reconnection of an interrupted session (eg for use in conjunction with UOWs and persistence) - I’ve not heard of it being used in the security mechanism.
Overhead for using Natural Security is similar to any other Natural Security logon - there are some Adabas calls involved to obtain the user’s record and groups. As with online/batch logons, the overhead is a function of the number of groups a user belongs to and the complexity of allow/denys of modules.
Douglas Kelly,
Principal Consultant
Software AG, Inc
Sacramento, California
The usage of Token together with security is usually mandatory in a multi-threaded middle-tier environment like IIS. Typically IIS keeps multiple instances of .NET (or COM) objects and processes them in multiple threads. If a session initiated by a web client is processed in one IIS thread there is a certain chance that a following call which belongs to the same session will be processed by IIS in a different thread. However, the Broker identifies a user by userid + physical/internal userid where the threadid is part of the physical userid. Once a thread change takes place Broker creates a new logical user and the security token is not valid any longer (because it belongs to another logical user). This is the reason why Token has to be used in such a scenario.
You might need multiple clients firing requests simultaneously to see this effect.
Kind regards,
Rolf
If you are interested in setting the userid only can you can do this directly by setting the RPCUserID property. The UserIDAndPassword is a convenience method to set both the userid and the password.
Kind regards,
Rolf
My comments:
- only token (if used) identifies a user session - not security token! And security token cannot be used in another session. A new logon is required for a new session and a new security token is returned for use with this session. A new session is required after a logoff and also when timed out by Broker. A security token can only be used for the session it was assigned.
- “Logon option=S” does not result in *USER being assigned with user-id of the client. It is the “service logon” on client side (which sends RPC logon data) that does this. This results in a Natural Logon being performed on the server side. Requesting RPC logon data can be forced by specifying LOGONRQ=ON on server side.
“Logon option=S” does only require that the user-id in the RPC logon data is identical to the user-id supplied in the Broker logon. If no service logon is done the server is running with *USER of the server.
Kind regards,
Mogens
Dear Rolf
I?ll let my main frame colleagues comment on the first part of your answer.
I realize that the UserIDAndPassword is a convenient method to set both the userid and the password, but I all ready tried setting the RPCUserID property alone like this:
s.RPCUserID = b.UserID;
However, this results in the somewhat misleading Natural error:
NAT0818 User ID is missing
It only seems to work setting both values:
s.RPCUserID = b.UserID;
s.RPCPassword = “NOPASSWORD”;
similar to my original code:
s.UserIDAndPassword(b.UserID,“NOPASSWORD”);
So Rolf, why do I get the error, and is there any elegant solution (on my end)?
Dear Rolf
Your fine explanation of token usage in an IIS environment is similar to that of our SAG consultant. I haven?t tried testing with multiple clients firing requests simultaneously without setting the token to the session id, but I?m sure you are right.
Instead I have run my test (once again) where I change the value of the token (initially set to the session id) during a session, expecting an error. And this time I do an error:
0080003 Acces Denied Password not authorized
Perhaps this is even the same error as if a thread change had taken place without assigning the token parameter?
I have no idea why I didn?t get this error in my first test run, but I?m sure I?m the one to blame, so what can I say: About token and security token, you were right, I was wrong.
Best regards,
Michael Brandt Lassen
It?s unclear to me what kind of sessions Mogens talks about in this first bullet? IIS-sessions?
Best regards,
Michael Brandt Lassen
SiD, Denmark
Hej Michael;
The token specified in the TOKEN field in the Control Block identifies a user session in the Broker.
A session in Broker can be thought of as any unterminated, un-timed-out conversations.
If you do not specify a TOKEN then in effect the user session is bound to the current process. If you do specify a token, then any process can reuse the same USERID and TOKEN to continue the Broker session.
from the documentation:
mvh
- arp
Thanks for your great answers.
I would still love to see more answers to these general questions:
? Is our use of the .NET Wrapper and EntireX Security as described above sound?
? What are the strengths and weaknesses of our solution?
? Where could we choose to do otherwise?
? Is there any secure alternatives to *USER passing the username to the Natural subprograms?
Best regards
Michael Brandt Lassen
SiD (soon 3F), Denmark
I was only checking the .NET Wrapper API and what’s happening there seems to make sense. Looks like something is going wrong probably on the Natural side. In case this is important for you please open a support request.
Kind regards,
Rolf