Wednesday, April 1, 2015

Conditional Redirect in SignOn PeopleCode

There are several scenarios where we might want to conditionally redirect users in SignOn PeopleCode. We cannot use the %Response.RedirectURL(location) method to achieve this because it does not work in SignOn PeopleCode.

There is a delivered function called SetAuthenticationResult which can be used for redirecting users in SignOn PeopleCode. Here is how we can use this feature (not very well documented in PeopleBooks):

E.g.: SetAuthenticationResult( False, &userid, &redirectURL, False);

Note: For this redirect to work, we need to change your Web Profile Configuration > Look and Feel (Tab):
Set Signon Result Doc Page to signonresultdocredirect.html


Information from Help:


Note: The web server(s) needs to be restarted for any changes in the web profile to take effect.

P.S.: This post is based on my response to a question in OTN.

53 comments:

  1. What's the format of &redirectURL, is it just a relative path to the page that we want to redirect to on the web server?

    ReplyDelete
  2. @Mike - the &redirectURL is the absolute URL to where we want to redirect. This does not necessarily have to be located on the web server (it could).

    I have always used the absolute path and it has worked for me in both cases. That is redirects to a page on the web server and redirects to external web pages.

    Let me know if you have any other questions. Thanks!

    ReplyDelete
  3. Hi, we configured our web profile look and feel to the signonresultdocredirect.html, but when we issue the etAuthenticationResult( False, &userid, &redirectURL, False); command in Signon peoplecode, it doesn't redirect to the URL, it just prints the text of the variable on the signon page. Is there something we missed? We can access our custom html page from outside of Peoplesoft, so we know the web server is seeing it.

    ReplyDelete
  4. @Mike - I have seen this behavior when the SignOn Result Doc Page is still pointing to signonresultdoctext.html. I think that is probably the issue.

    Few basic things (sorry if you already checked these):
    - Are you sure you are making the change to the correct web profile? You can check that by logging on to web server using SSH.
    Directory: /<%PS_HOME%>/webserv/<%DOMAIN_NAME%>/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/<%DOMAIN_NAME%>
    File: configuration.properties
    Property: WebProfile

    - Did you restart your web server after you made the change to the web profile?

    - Check if signonresultdocredirect.html exists on your web server:
    Directory: /<%PS_HOME%>/webserv/<%DOMAIN_NAME%>/applications/peoplesoft/PORTAL.war/WEB-INF/psftdocs/<%DOMAIN_NAME%>

    Also, i don't think it is an issue with the access to the custom page (if you can get to it from outside of PeopleSoft).

    ReplyDelete
  5. Hello - I am ashamed to ask, but where did you apply this method? SetAuthenticationResult( False, &userid, &redirectURL, False);
    I am not sure where to find the Signon People code.

    Thanks

    Terry

    ReplyDelete
    Replies
    1. Hi Terry,

      Nothing to be ashamed about! It is a very valid question. I should have included the details in my post for more clarity. I am glad you ask it now! :)

      Basically, all signon peoplecode events that run in a particular environment during the login event are configured in the following page:
      Main Menu > PeopleTools > Security > Security Objects > Signon PeopleCode

      Any peoplecode code function (these are all record peoplecode functions) that is listed and enabled on this page would get fired.

      You might find some delivered functions are enabled (such as LDAP_Authentication) on this page as well as any custom functions your organization might have included.

      You can invoke SetAuthenticationResult in any of those functions.

      Hope this helps clarify! Let me know if you have any other questions.

      Refer the following PeopleBook for more information on SignOn PeopleCode:
      http://docs.oracle.com/cd/E26239_01/pt851h3/eng/psbooks/tsec/chapter.htm?File=tsec/htm/tsec09.htm

      Thanks,
      Sasank

      Delete
    2. Hi Sasank,
      Thanks for this informative post. It really gives us a direction for our signon problem. I had one question though, once we make this config change ( web profile pointing to signonresultdocredirect.html ), in the signon peoplecode, do we still have to specifiy a value for the &redirectURL variable or it would automatically redirect the user to signonresultdocredirect.html ?

      Delete
    3. @Nishant - Yes. You still need to specifiy the redirect URL. We need to note that the signonresultdocredirect.html is a very basic HTML page. All it does is a redirect using the following code.

      <meta HTTP-EQUIV='Refresh' CONTENT='1; URL=<%=resultDoc%>'>

      So, the goal should be to use the signonresultdocredirect to redirect the users to another page rather than simply redirecting the users to signonresultdocredirect.html. Because that page would not have any information for the end user.

      Hope this makes sense. Let us know if you have any other questions!

      Delete
  6. Hi Sasank - Below is what I have, but it is not re-directing. Any suggestions on what to do next?

    Thanks

    Terry


    &redirectURL = GenerateComponentContentURL(%Portal, %Node, MenuName."ADMINISTER_WORKFORCE_(GBL)", "GBL", Component.PERSONAL_DATA1, Page.PERSONAL_DATA1, "U", %SignonUserId);

    SetAuthenticationResult( False, %SignonUserId, &redirectURL, False);

    ReplyDelete
    Replies
    1. Hi Terry,

      I have not used the setauthenticationresult for redirection to internal PeopleSoft page. I usually use it for redirecting to an external link so in most cases I fail the authentication result (AuthResult parameter) with a false in the first parameter.

      In your case, since you are redirecting to an internal PeopleSoft page, you would need to set the AuthResult parameter to true as follows:

      SetAuthenticationResult( True, %SignonUserId, &redirectURL, False);

      Also, all this will only work if the web profile settings Signon Result Doc Page is set to signonresultdocredirect.html as mentioned in this post.

      Let us know if you run into any further issues!
      Thanks,
      Sasank

      Delete
    2. I'm getting a redirect loop when I redirect to an internal page. For some reason, my signon peoplecode is executing twice!

      SetAuthenticationResult( True, TESTUSER, &absolute_url, False, 0);

      Delete
    3. SignOn PeopleCode executing twice is probably not an issue. It will execute for the second time since the SetAuthenticationResult is redirecting to a new URL.

      Anytime a redirect happens, SignOn PeopleCode should and would get fired again. Only that, in the second/subsequent instance, if we already have an established PS_TOKEN then the user would go through without issues. If you are having failures when the SignOn PeopleCode executes the second time, then you might want to write some code to check if a valid PS_TOKEN exists and let the user in based on that.

      As I said, I generally do not use this for redirecting to an internal page. I take it that by internal page, you mean a page inside the PeopleSoft application?

      FWIW, I tried redirecting to the PeopleSoft Process Monitor page and it seems to work. As you mentioned, the code is executing twice but that is expected.

      Let us know if you are still having issues. Thanks!

      Delete
  7. Hi Sasank,

    Hope you are doing good. My question is similar to this topic.Don't scold me, if this is already discussed here..

    We have been sending email to user in which we have provided internal peoplesoft link (say for example process monitor page, as you mentioned). When we clicks on the link or copy paste the URL, it is asking for credentials in the login page.. This is excellent.. But the problem is that URL automatically gets changed to default sign-on URL (instead of our expected peoplesoft internal URL). when we enter username and password and hit login, we are going to Peoplesoft Main Menu homepage. If it is the behavior, there is no point of sending destination URL in the email right?? This is quite frustrating...

    Do you have any thoughts how to overcome this?

    Thanks in advance!!!

    Cheers,
    Raghu

    ReplyDelete
    Replies
    1. @Raghu R - What tools version are you on? This functionality should work by default. Can you try the same (e.g.: accessing the process monitor URL) on your demo/vanilla environment?

      Also, have you made any customizations to the signin.html file on the web server?

      Like I said, this should work out of the box (at least since 8.50 on wards based on my experience). Just as a side note, this functionality described by you is not really related to (and not to be confused with) the conditional redirect.

      Delete
    2. Hi Sasank,

      Thanks for your response.
      We are using PT 8.54.xx. I was also trying to check this on web server level that any customization done.
      No URL's are working, it automatically redirects to sign-on page. It looks like some customization done signin.html file.

      Thanks,
      Raghu

      Delete
    3. Hi Raghu/Sasank,

      We have similar issue after we upgrade to PeopleTools 8.55. Did you find any solution this?

      Thanks,
      Manhoar

      Delete
    4. Hi Manohar - I have not experienced this issue myself. This functionality should work by default. You may want to created an Oracle Support service request.

      Delete
    5. Thanks Sasank. I have opened a ticket for Oralce Support.

      Delete
    6. It is issue in PeopleTools 8.55.14 but works in 8.55.11

      Delete
    7. we are phasing the same issue after we upgrade to tools 8.55.14. How did you resolved it?

      Delete
  8. Is it possible to send http_referrer information or use %Response.SetHeader(http_referrer, &myURL) with SetAuthenticationResult( True, %SignonUserId, &RedirectURL, False); in the Signon Peoplecode. I discovered that it uses meta HTTP-EQUIV='Refresh' CONTENT='1; URL=MyURL'> as the method to redirect. I would like to included a custom header to use for deeplinking with external authentication.

    ReplyDelete
    Replies
    1. Hi Isa - Great question. I understand what you are trying to do.

      I don't think you can add http headers using SetAuthenticationResult or use the response object in signon peoplecode.

      But one workaround that I can think of (might seem a little bit of an overkill):
      - Use SetAuthenticationResult to redirect to an IScript:
      E.g.:
      SetAuthenticationResult( True, "GUEST", "https://www.test.com/psc/ps/EMPLOYEE/HRMS/s/WEBLIB_SV_TST.ISCRIPT1.FieldFormula.IScript_SASANK", False);

      Depending on whether you want to authenticate to success or failure you can use the %signonuserid (success) or a GUEST style userid (failure).

      - In the IScript you will need to redirect to your external URL and add the header using the response object (SetHeader and RedirectURL methods).

      I tried this and it works. So the flow would be as follows user login > signon peoplecode > setauthenticationresult (signonresultdocredirect.html on web server) > IScript > external URL.

      Hope this gives you some ideas. Thanks!

      Delete
  9. I have a requirement to open a XMLP/BI report from a REST Web service call from 3rd party. Created rest service and provided WADL. In the handler peoplecode added code to generate XMLP in PDF format and used dispalyoutput method of XMLP. But can see the response without any PDF is opened. PDF is generated, hence tried viewattachment. but didn't work. DO I need http post, appariciate any help

    ReplyDelete
    Replies
    1. Venu - I don't believe you can use the displayoutput method for streaming documents via Integration Broker. To my knowledge, that method would only work if the request is made via a PeopleSoft page (PIA).

      You could move your code to an IScript. In the IScript you can try the displayoutput and see if it works. I am not sure if it works but you will have several options once you are in the IScript framework.

      Note: From a third party point of view, an IScript could just be similar to a HTTP GET.

      Thanks!

      Delete
  10. Hi sasank

    I posted the question to wrong post(XMLP/BI report open). Sorry about that. Any direction is greately appriciated.

    ReplyDelete
  11. Hi - Am trying to add a prefix to URL - add additional prefix to the PS server. Can we add this to the signon.html?

    All the subsequent validation of the re-directions are taken care-off in signon peoplecode

    Thanks,
    Srini

    ReplyDelete
    Replies
    1. Hi Srinivas - Can you please explain this with an example? I am not sure I understand your requirement.

      Delete
    2. Hi Sasank - We are trying to authenticateusing thirdparty authentication system which issues a ticket. We need to by-pass the PS Authentication which we could do it through the web profile.

      However when we connect to PS - we need to get re-directed, authenticated by the third party system,validate the ticket in PS & set the authentication result.

      The problem is PS -> thirdpaty application -> PS. the re-direction back to PS is what we are struck on

      -Srini

      Delete
    3. Srini - Is this third party authentication CAS (Central Authentication Service?

      Anyway, I have worked with CAS which is very similar ticket based system. This is how I tackled the PS authentication.

      - On the sign.html file, I placed a redirect to CAS for authentication. So, basically, bypassing PS Authentication. The redirect URL would be something like this:
      https://cas.test.com/cas/login?service=https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/h/?tab=DEFAULT

      You can see that the service parameter is the PS Homepage URL.

      - Then once authenticated with CAS, CAS will redirect to the service URL, which is https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/h/?tab=DEFAULT. At this point, my signon peoplecode would kick in and verify the CAS ticket. Once the ticket is verified, I would authenticate the user. If the ticket is not verified, I would redirect back to CAS using SetAuthenticationResult.

      Hope this gives you some ideas.

      Delete
    4. Hi Sasank - Yes,we are using the CAS integration, what we are doing are in similar lines. we want PS to re-direct to authentication system & return with the ticket. Basically, when we do such a thing it works for default page without any issues. However, for the deep rooted links the signin.html is not taking the re-direction at all. If you can send me more details of changes in signin.html will be quite helpful

      Thanks,
      Srini

      Delete
    5. Srini - The signin.html should not come into play for the deep links or even the homepage URL. If an user accesses a deep link (e.g.: https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/c/MAINTAIN_SECURITY.USERMAINT.GBL) or the homepage URL (e.g.: https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/h/?tab=DEFAULT), the signon peoplecode for CAS ticket validation should kick in at this point. The user would not go to the signin page in this scenario.

      In the signon peoplecode, are you checking if the ticket exists and validating accordingly? I think that your problem may be with redirecting to CAS when the ticket does not exist. You should be using a setauthresult call (detailed in this post) and redirect to CAS with service URL.
      E.g.:
      ...
      &redirectURL = &cas_redirect_url | "service=" | &ServiceURL;
      SetAuthenticationResult( True, "CSK_GUEST", &redirectURL, False);
      ...
      where &redirectURL would be something like https://cas.test.com/cas/login?service=https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/c/MAINTAIN_SECURITY.USERMAINT.GBL

      You may want to consider using EncodeURLForQueryString on the &redirectURL.

      On the signin.html, it is just a simple redirect and it will only be invoked if someone directly access the login page. Here is a snippet:

      Delete
    6. Could not paste the html/script in the comments. You can find it here:
      https://pe0ples0ft.blogspot.com/p/signinhtml-code-snippet.html

      Delete
    7. Hi,

      I am busy implementing CAS with PeopleSoft. However, I could get the signon peopleCode to be triggered for validating the ticket. Please could you kindly help? What is the workflow? What are the PeopleSoft files to modified (signing.html or signon.html ...etc)?

      Your help would be really appreciated.

      Best Regards
      MDABO

      Delete
    8. It really depends on your implementation. There are several online resources available that should get you started on the entire architecture and objects involved:

      https://wiki.jasig.org/display/CAS/CASifying+PeopleSoft
      http://www.slideshare.net/JohnGasper1/casifying-peoplesoft-and
      https://www.scribd.com/document/281610104/University-of-Northern-Iowa-PeopleSoft-CAS-Configuration-Public

      Delete
    9. Hi Sasank,
      Thanks for your quick answer. I had look already those documentation. However for all the settings I have tried, the peopleCode signon is not triggered. Or if triggered, the ticket is missing from %Request object in the signon PeopleCode.

      If you have already implemented CAS/PS, could you kindly help?

      Best Regards
      MDBABO

      Delete
    10. Unfortunately, I don't have any other documents/steps to offer other than the links above. My experience with CAS is loosely based on the following document (which is part of the first link that I previously shared):
      https://wiki.jasig.org/download/attachments/5645/CalPolyWebLogin.pdf?version=1&modificationDate=1343241066721&api=v2

      If you are not seeing the ticket in the Request Class, then it means that CAS is unable to authenticate the user, the user is not logged in or the user's session expired.

      Delete
  12. Thanks Sasank. We are using the URL directly as https://cas.test.com/login?service=PS URL

    We are validating the ticket in the signon peoplecode & setting the authentication result. This is working for all links. However, we want PS to call CAS URL for validation. If I understand correctly, you have the PS URL which on signin calls the the function in signin.html to re-direct to CAS portal login. For the deep rooted links, you handle through the re-direct URL in signon peoplecode. When you re-direct the URL - on CAS authentication, does this not fire the signon peoplecode again? After this portal issues the CAS ticket & then you validate the ticket.Hope I got this right?



    Thanks,
    Srini

    ReplyDelete
    Replies
    1. When you re-direct the URL - on CAS authentication, does this not fire the signon peoplecode again?
      Yes. When I redirect to CAS with service=SOME_PS_URL, the control gets passed to CAS, CAS then sees if the session is valid and would redirect back to PS (SOME_PS_URL?&ticket=xyz123) with a ticket if it is valid. Then signon peoplecode fires again, but this time because there is a ticket in the query string, the signon peoplecode does the validation directly using the java class. Once the validation is successful, the user will be authenticated.

      Delete
    2. Thanks for the info. What do you pass at the portal login URL is this the full complete URL - cas.test.com/login?service=

      Delete
    3. Just the homepage URL. Basically, this is where the users even if they authenticate against PeopleSoft.

      E.g.: https://cas.test.com/cas/login?service=https://pi017.hcm92.com/psp/ps/EMPLOYEE/HRMS/h/?tab=DEFAULT

      Also, none of the users would purposely try to access the signin.html. Because they would usually go to CAS as their starting point. The above redirect is only for those users who end up on the login page accidentally. Hope this makes sense.

      Delete
    4. Many Thanks for the inputs, will try them out.

      Delete
  13. Hi Sasank,
    First of all thanks for this interesting post!

    I am trying to implement a scenario with conditional redirect: when an LDAP authentication fails, I would like to redirect the user to the internal PeopleSoft login page with a customer message depending of the LDAP response (like account is locked, disabled …etc).
    I have tried different times using the following method and parameters SetAuthenticationResult( False, %SignonUserId, &redirectURL, False). However I am facing issue using this function. What I have noticed is that, when the authentication fails, the value of the parameter %SignonUserId is different the value that user has entered into the login form. Thus the redirect is not working. Do you have any idea?

    P.S.: Note that the SetAuthenticationResult ( True, %SignonUserId, &ExternalredirectURL, False) works well for example when an authentication is success and the redirect url is an external site.

    Best Regards
    Nash

    ReplyDelete
    Replies
    1. Hi Nash - I have not tried using the redirect with a false authentication. In my experience, the redirect only seems to work if the authentication is true. A workaround though, is to set the authentication to true using a guest style userid (E.g.: GUEST) and then redirect.

      E.g.:
      SetAuthenticationResult( True, "XXX_GUEST", "https://www.google.com", False);

      Note: XXX_GUEST should be an unlocked userid with minimal access. In fact, it does not even need any roles assigned.

      I know this is not ideal but that is the approach I took when I ran into this issue. Let us know if you find an alternative way to get around the problem.

      Delete
  14. Sasank,

    I've got this close to being setup. I have placed the following code in LDAPAUTH FieldDefault, however, the code is being executed in an infinite loop and will not complete the redirect. The browser just constantly refreshes.

    Function LDAP_REDIRECT()
    If %PSAuthResult = True Then
    Local string &signonUserID;
    &signonUserID = %SignonUserId;
    SetAuthenticationResult( True, &signonUserID, "/psp/ps/EMPLOYEE/HRMS/h/?tab=DEFAULT", False, 0);
    End-If;
    End-Function;

    I have made sure to modify the web profile look and feel to point to signonresultdocredirect.html, and all that's in the HTML are the html and head tags as well as this::

    {meta HTTP-EQUIV='Refresh' CONTENT='1; URL=<%=resultDoc%>'}


    Any idea why my signin peoplecode is being executed in an infinite loop? Thanks!

    ReplyDelete
    Replies
    1. Hi Jes - Not sure why you are trying to redirect the user to the homepage? Can you try simply using the SetAuthenticationResult without a URL? Won't it go to the homepage anyway?

      Also, if %PSAuthResult = True then there may be a valid PS Token already. Correct? In that case, if you redirect again, the SetAuthenticationResult redirects back to the same URL, signon peoplecode fires again and it will keep redirecting infinitely.

      Delete
    2. What I am trying to do is redirect users to the Classic homepage, and not the Fluid home page. Thanks for the reply!

      Delete
    3. Hi Jes - Are you on 8.55? If so, you could consider using the following option:
      http://www.peoplesoftmods.com/emf/classic-ui-for-administrative-users/

      Even if you are not on 8.55, you could still add custom code to the Fluid Homepage component to perform the redirect as detailed in Colton's post.

      Delete
  15. Awesome, thanks Sasank!

    ReplyDelete
  16. Hi Sasank,

    Thank you for your article. I have successfully developed a functionality to redirect users to a financial agreement page in CS 9.0/PT8.54.12 release based on your article. User will be redirected to the home page upon accept button click or sign out upon decline button click. This worked wonderful until we upgraded PeopleTools to 8.55.14 release recently. The component becomes unresponsive after the redirect (Clicking on Accept/Decline buttons won't work). Even the sign out link in the upper right corner link never works. Have you come across this issue with PT8.55.14? We are planning to go live with classic mode first and implement Fluid later on. I have opened a SR for this issue on MOS site.

    - Khaliq

    ReplyDelete
    Replies
    1. Khaliq - Sorry to hear that it is not working in 8.55.14. I have not seen this behavior. Hopefully, MOS will be able to assist. If you find a solution then let us know!

      I will try to test this if I can and let you know my results. What is the navigation to this financial agreement page? Is it delivered or custom?

      Delete
  17. Very Interesting use of the Redirect parameter.
    I'm wondering if we can use this to overcome my biggest issue with Default User Sign In.

    We have a Interaction Hub <--> HCM <--> <--> ELM setup in PeopleSoft. Ideally, i would like to users to start in Interaction hub with Guest Access.

    Users will by default goto the (EMPLOYEE/EMPL/c/NUI_FRAMEWORK.PT_LANDINGPAGE.GBL) and will be automatically logged in with the Guest User and see the 'Guest Fluid Home Page'. This will have the 'Sign In' Tile, plus other tiles (Company News, Organization Directory) etc.

    Users will Sign in (using the Sign In til) to gain access to Self Service applications.

    But the problem comes in when they access a deep-linked (Say Manager gets a notification to approve Staff's leave request and it has a direct URL to the transaction)

    Default Behavior:
    a. Manager Clicks 'deep' link
    b. Views Sign On page & signs in with credentials
    c. Views the Approval Transaction

    Consider if the Manager has already opened the 'Guest' homepage in his browser.
    He just gets an email notification and clicks the Link. Now PS tries to navigate in the context of already logged in user 'Guest' which does not have access to the Approval page.

    Wonder if we can catch this scenario using the Sign-On.

    Something like

    If %SignOnUserID = 'Guest' and %PSAuthResult = True Then
    If 'Guest' authorized for Menu/Component/Page Then
    Proceed
    Else
    SetAuthorization(False,%SignOnUserID, , False)
    End
    End


    ReplyDelete
    Replies
    1. Yes. You should be able to write some conditional logic on the HCM side to redirect to the login page, in case someone (say a Manager) accesses a deep-link in an email that would automatically take them in as a guest.

      Delete