VISTA Auto Signon

From VistApedia
Jump to: navigation, search

Setting Up VISTA Auto Sign-on

VISTA Auto Sign-on (aka Single Sign-On, SSO) that doesn't rely on CCOW can be accomplished as follows:

You need to have the RPC Client Agent running on your machine. You can get this from this set-up program here: https://downloads.va.gov/files/vista/Software/VISTA_FOIA_RELEASES_BEFORE_2008/RPC%20Broker%20-%20XWB/PROGRAMS/XWB1_1WS.EXE or in the BDK folder of the CPRS Source Code.

The other thing you need to do is enable Auto-Sign on either at the user level or the Kernel Level.

DEFAULT AUTO SIGN-ON in KERNEL SYSTEM PARAMETERS

or

AUTO SIGN-ON in NEW PERSON

Once you run clagent.exe, you will see the image of a little satellite dish in your system tray.

Once you sign-on (first sign-on is required) using roll and scroll or any client, the satellite lights up. It means that you are signed into VISTA. Any subsequent sign-on in a client that supports it (not Scheduling at the moment) will auto-sign you in.

In order to auto-sign on a user, you need to call the RPC named XUS SIGNON SETUP, and check the return value of subscript 5 and see if it is 1. If it is, then Auto-Sign on succeeded.

Here is the Delphi Code from RpcSLogin.pas:

{:
This function is used to initiate a silent login with the RPCBroker.  It uses the information stored in the Login property of the TRPCBroker to make the connection.
}
function SilentLogIn(SLBroker: TRPCBroker): boolean; begin
  Result := False;
  //determine if signon is needed
  try
    with SLBroker do begin
      RemoteProcedure := 'XUS SIGNON SETUP';
      Call;
      SLBroker.Login.IsProductionAccount := False;
      SLBroker.Login.DomainName := '';
      if SLBroker.Results.Count > 7 then
      begin
        SLBroker.Login.DomainName := SLBroker.Results[6];
        if SLBroker.Results[7] = '1' then
          SLBroker.Login.IsProductionAccount := True;
      end;
      if Results.Count > 5 then    //Server sent auto signon info.
        if SLBroker.Results[5] = '1' then   //User already logged in
        begin
          Result := True;
          GetUserInfo(SLBroker);
          exit;
        end;
      if Login.Mode = lmAVCodes then //Access & Verify codes authentication
        if ValidAVCodes(SLBroker) then Result := True;
      if Login.Mode = lmAppHandle then
        if ValidAppHandle(SLBroker)then Result := True;
      if Login.Mode = lmNTToken then
          if ValidNTToken(SLBroker) then Result := True;
      if Result and (not (SLBroker is TCCOWRPCBroker)) then
      begin
        //determine if user is multidivisional - makes calls to Seldiv.
        LogIn.MultiDivision := MultDiv(SLBroker);
        if not LogIn.MultiDivision then
          begin
          Result := True;
          exit;
          end;
        if LogIn.PromptDivision then
          Result := SelectDivision(LogIn.DivList, SLBroker)
        else if Login.Division <> '' then
          Result := SetDiv(Login.Division, SLBroker)
        else
        begin
          Result := False;
          Login.ErrorText := 'No Division Selected';
        end;
        if not Result then
          exit;
      end;
      if Result then
        GetUserInfo(SLBroker);
    end;
  except
    exit;
  end;
end;

procedure GetUserInfo(ConnectedBroker: TRPCBroker); //get info for TVistaUser; begin
  with ConnectedBroker do
  begin
    try
    RemoteProcedure := 'XUS GET USER INFO';
    Call;
    if Results.Count > 0 then
      with ConnectedBroker.User do
        begin
        DUZ := Results[0];
        Name := Results[1];
        StandardName := Results[2];
        Division := Results[3];
        Title := Results[4];
        ServiceSection := Results[5];
        Language := Results[6];
        DTime := Results[7];
        if Results.Count > 8 then
          Vpid := Results[8]
         else
          Vpid := '';
        end;
    except
    end;
  end;
end;

How does Auto Sign-on Work

When you try to sign-on to VISTA applications that support SSO, they will make a call from the server side to the client side on port 9200, where the client agent is listening. So, let's say your CPRS is signing on. The 3rd RPC it sends is XUS SIGNON SETUP. This RPC will do a call back to the client running CPRS on port 9200 if SSO is running. If it gets a connection (isn't refused by the machine or blocked by firewalls), it will send a message to the client called XWB GET HANDLE. The client will reply back with XWB QUERY RESPONSE, to tell the server whether a handle has already been created for a previous application that logged on using an access and verify code. If the server decides that the handle is valid, it will call the client with XWB CREATE HANDLE.

Here is an example of server callback when nobody else has connected before:

{XWB}000051064200015XWB GET HANDLES00000.{XWB}000051064200018XWB QUERY RESPONSE00000.

Here is an example of server callback when somebody has connected before (2 separate calls):

{XWB}000051117800015XWB GET HANDLES00000.{XWB}000051117800018XWB QUERY RESPONSE0000813766580.
{XWB}000051064200017XWB CREATE HANDLE00027HABIEL,SAM M^3110608.132432.{XWB}000051064200018XWB QUERY RESPONSE0000811970625.

The output of fifth subscript of the call XUS SIGNON SETUP is 0 or 1. If it is 1, then Single Signon succeeded, and the server can continue without authenticating the user again.

What if the user has not signed on before and an access and verify code need to be entered? In that case, the server makes the following call to the client machine after the client has authenticated using the RPC XUS AV CODE:

{XWB}000051064200017XWB CREATE HANDLE00027HABIEL,SAM M^3110608.132432.{XWB}000051064200018XWB QUERY RESPONSE0000811970625.

Once this is executed, the client has a handle which it can supply to the server when it is queried using XWB GET HANDLE. If that handle is supplied, the server will check it in the ^XUSEC(0) global to see if it is valid. If it is, we can auto-sign on the user.

Let's look at the other end of the loop: When the client says #BYE# to the RPC Broker, XWB code deletes the handle by calling back the client as follows:

{XWB}000051064200017XWB DELETE HANDLE0000811970625.{XWB}000051064200018XWB QUERY RESPONSE00007DELETED.

There is one last case scenario which we need to consider.

Here's a summary:

Auto-signon server calls vs client RPCs
Client RPC Call Server Callback for SSO Client Reply for SSO
XUS SIGNON SETUP XWB GET HANDLE (& XWB CREATE HANDLE if SSO'ed) XWB QUERY RESPONSE
XUS AV CODE (doesn't take place if SSO'ed) XWB CREATE HANDLE XWB QUERY RESPONSE
#BYE# XWB DELETE HANDLE XWB QUERY RESPONSE


In the M code, LOG^XUS1 is called following a sign-on to 'create' the log-in cookie.

What about sign-ons using ^ZU? They make the same sequence of events.