Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions src/opendap/auth/IdFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,25 @@ private void init() throws IOException, JDOMException {

}

void doUnathorized(Exception e, HttpServletRequest req, HttpServletResponse resp, IdProvider idProvider) throws IOException {
String msg = "Your Login Transaction FAILED! " +
"Authentication Context: '"+idProvider.getAuthContext()+
"' Message: "+ e.getMessage();
log.error("doForbidden() - {}", msg);
OPeNDAPException.setCachedErrorMessage(msg);
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED,msg);
}

void doForbidden(Exception e, HttpServletRequest req, HttpServletResponse resp, IdProvider idProvider) throws IOException {
String msg = "Your Login Transaction FAILED! " +
"Authentication Context: '"+idProvider.getAuthContext()+
"' Message: "+ e.getMessage();
log.error("doForbidden() - {}", msg);
OPeNDAPException.setCachedErrorMessage(msg);
resp.sendError(HttpServletResponse.SC_FORBIDDEN,msg);
}

public void doFilter(ServletRequest sreq, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain filterChain) throws IOException, ServletException {

// Ensure initialization has been accomplished
if (!isInitialized) {
Expand All @@ -178,6 +195,7 @@ public void doFilter(ServletRequest sreq, ServletResponse response, FilterChain
try {

HttpServletRequest request = (HttpServletRequest) sreq;
HttpServletResponse response = (HttpServletResponse) sresp;
RequestCache.open(request);
RequestId requestId = RequestCache.getRequestId();

Expand Down Expand Up @@ -277,13 +295,8 @@ else if (enableGuestProfile && requestURI.equals(guestEndpoint)) {


} catch (IOException | Forbidden e) {
String msg = "Your Login Transaction FAILED! " +
"Authentication Context: '"+idProvider.getAuthContext()+
"' Message: "+ e.getMessage();
log.error("doFilter() - {}", msg);
OPeNDAPException.setCachedErrorMessage(msg);
((HttpServletResponse)response).sendError(HttpServletResponse.SC_UNAUTHORIZED,msg);
log.debug("END (session: {})",session.getId());
doForbidden(e, request, response, idProvider);
log.debug("END (session: {})", session.getId());
return;
}
}
Expand Down Expand Up @@ -341,6 +354,8 @@ else if (enableGuestProfile && requestURI.equals(guestEndpoint)) {
}
catch (Forbidden http_403){
log.error("Unable to validate Authorization header. Message: "+http_403.getMessage());
Copy link
Contributor Author

@ndp-opendap ndp-opendap Sep 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a reason this was not throwing an exception prior to this. Throwing an exception here will break things - we need to reevaluate this bug and see if there's a better way to fix it.

doForbidden(e, request, response, idProvider);
log.debug("END (session: {})", session.getId());
}
}
}
Expand Down
26 changes: 18 additions & 8 deletions src/opendap/coreServlet/OPeNDAPException.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -187,26 +188,36 @@ public final void setErrorMessage(String msg) {
}



/**
* ************************************************************************
* Recasts any Throwable to be an OPeNDAPException and then transmits it
* on to the passed stream as a DAP2 error object. If the passed Throwable
* is already an OPeNDAPException, it is not recast.
*
* @param t The Exception that caused the problem.
* @param servlet The current servlet. Used to find things shipped in the deployment.
* @param response The <code>HttpServletResponse</code> for the client.
*/
public static int anyExceptionHandler(Throwable t, HttpServlet servlet, HttpServletResponse response) {
return anyExceptionHandler(t, servlet.getServletContext(), response);
}

Logger log = org.slf4j.LoggerFactory.getLogger(OPeNDAPException.class);

/**
* ************************************************************************
* Recasts any Throwable to be an OPeNDAPException and then transmits it
* on to the passed stream as a DAP2 error object. If the passed Throwable
* is already an OPeNDAPException, it is not recast.
*
* @param t The Exception that caused the problem.
* @param servletContext The servlet context. Used to find things shipped in the deployment.
* @param response The <code>HttpServletResponse</code> for the client.
*/
public static int anyExceptionHandler(Throwable t, ServletContext servletContext, HttpServletResponse response) {

Logger log = org.slf4j.LoggerFactory.getLogger(OPeNDAPException.class);
try {

log.error("anyExceptionHandler(): " + t);


ByteArrayOutputStream baos =new ByteArrayOutputStream();
PrintStream ps = new PrintStream( baos, true, HyraxStringEncoding.getCharsetName());
t.printStackTrace(ps);
Expand All @@ -232,14 +243,13 @@ public static int anyExceptionHandler(Throwable t, HttpServlet servlet, HttpServ

oe = new OPeNDAPException(UNDEFINED_ERROR, msg);
oe.setHttpStatusCode(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

}

if(!response.isCommitted()){

response.reset();

oe.setSystemPath(ServletUtil.getSystemPath(servlet,""));
oe.setSystemPath(ServletUtil.getSystemPath(servletContext,""));
try {
oe.sendHttpErrorResponse(response);
}
Expand Down Expand Up @@ -504,7 +514,7 @@ public void sendAsHtmlErrorPage(HttpServletResponse response) throws Exception {
// for the JSP to retrieve. The RequestCache for this thread gets destroyed when the doGet/doPost
// methods exit which is normal and expected behavior, but the JSP page is invoked afterward so we
// need a rendezvous for the message. We utilize this errorMessage cache for this purpose. The only
// public method for retrieving the message is tied to the thread of execution and it removes the
// public method for retrieving the message is tied to the thread of execution, and it removes the
// message from the cache (clears the cache for the thread) once it is retrieved.
_errorMessageCache.put(Thread.currentThread(), getMessage());

Expand Down