Written by

Senior Development Manager at InterSystems Corporation
Question Timothy Leavitt · Apr 6, 2022

Returning an HTTP 403 from %CSP.SessionEvents:OnStartRequest

Is there a way, given a %CSP.SessionEvents subclass, to simply return an HTTP 403 error status from OnStartRequest?

If I return an error %Status from the method, it'll go to the error page; if I don't, it's always a 200 OK and the page continues to render.

Product version: IRIS 2021.2
$ZV: IRIS for Windows (x86-64) 2021.2 (Build 651U) Mon Jan 31 2022 17:39:04 EST

Comments

Vitaliy Serdtsev · Apr 7, 2022

Try this:

<FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">OnStartRequest() </FONT><FONT COLOR="#000080">As %Status
</FONT><FONT COLOR="#000000">{
  </FONT><FONT COLOR="#0000ff">#dim </FONT><FONT COLOR="#800000">%response </FONT><FONT COLOR="#0000ff">As </FONT><FONT COLOR="#008080">%CSP.Response
  
  </FONT><FONT COLOR="#008000">;s %response.ContentType="text/html",%response.Expires=-1
  </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">%response</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Status</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%CSP.REST</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">#HTTP403FORBIDDEN
  q $$$OK
</FONT><FONT COLOR="#000000">}</FONT>
Or this:
<FONT COLOR="#000080">/// Event handler for <b>PreHTTP</b> event: this is invoked before
/// the HTTP headers for a CSP page have been sent.  All changes to the
/// <class>%CSP.Response</class> class, such as adding cookies, HTTP headers,
/// setting the content type etc. must be made from within the OnPreHTTP() method.
/// Also changes to the state of the CSP application such as changing
/// %session.EndSession or %session.AppTimeout must be made within the OnPreHTTP() method.
/// It is prefered that changes to %session.Preserve are also made in the OnPreHTTP() method
/// as this is more efficient, although it is supported in any section of the page.
/// Return <b>0</b> to prevent <method>OnPage</method> from being called.
ClassMethod </FONT><FONT COLOR="#000000">OnPreHTTP() </FONT><FONT COLOR="#000080">As %Boolean </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">ServerOnly </FONT><FONT COLOR="#000000">= 1 ]
{
  </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">%response</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Status</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"403 Forbidden"
  </FONT><FONT COLOR="#0000ff">q </FONT><FONT COLOR="#000000">0
}</FONT>
0
Timothy Leavitt  Apr 7, 2022 to Vitaliy Serdtsev

Here's the problem:

  • I need to do this in a session events class, as I want it to be reusable and apply to all resources in a given web application.
  • If OnStartRequest returns $$$OK, the page renders (%response.Status is set correctly, though).
  • If OnStartRequest returns an error, the web application's error page is shown.

The solution might be using a custom error page too.

0
Timothy Leavitt  Apr 7, 2022 to Timothy Leavitt

Simple solution:
Create a class extending %CSP.Page with:

ClassMethod OnPreHTTP() As %Boolean
{
    Set %response.Status = ##class(%CSP.REST).#HTTP403FORBIDDEN
    Quit 0
}

From the %CSP.SessionEvents subclass, in OnStartRequest:

set %response.ServerSideRedirect = "<that classname>.cls"
0