Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

How to get access to ServletContext object in custom implementation of HttpServerAuthenticationMechanism

212 views
Skip to first unread message

kumaran L

unread,
Jul 4, 2023, 1:10:38 PM7/4/23
to WildFly
Hi,

We have a custom implementation of HttpServerAuthenticationMechanismFactory and HttpServerAuthenticationMechanism for our application use case. I am wondering how I can get a handle to ServletContext object inside HttpServerAuthenticationMechanism. The HttpServerRequest object passed to evaluateRequest() method has only the current request details and there is no way to access ServletContext/DeploymentInfo.

One workaroung I could think of is to have a custom handler like below that gets init parameters from DeploymentInfo and set them as request parameters so that it can be accessed via HttpServerRequest in  HttpServerAuthenticationMechanism.


public class ApplicationContextHandler implements HttpHandler {    
     private final HttpHandler next;
     private final Map<String, String> initParamMap = new HashMap<>();

     public ApplicationContextHandler(final HttpHandler next, DeploymentInfo deploymentInfo) {
         super();
         this.next = next;
         init(deploymentInfo);
     }

     private void init(DeploymentInfo deploymentInfo) {
         Map<String,String> paramas = deploymentInfo.getInitParameters();
         Set<String> keys = paramas.keySet();
         keys.forEach(key -> initParamMap.put("application." + key, paramas.get(key)));
     }


     @Override
     public void handleRequest(final HttpServerExchange httpServerExchange) throws Exception {

         Set<String> keys = initParamMap.keySet();
         keys.forEach(key -> httpServerExchange.addQueryParam(key, initParamMap.get(key)));
         next.handleRequest(httpServerExchange);
     }


 }

Is there better way to do this?

Regards,
Kumaran

Paul Ferraro

unread,
Jul 4, 2023, 1:42:55 PM7/4/23
to WildFly
Why not implement the standard Jakarta EE HttpAuthenticationMechanism interface instead?  i.e. https://jakarta.ee/specifications/platform/10/apidocs/jakarta/security/enterprise/authentication/mechanism/http/httpauthenticationmechanism
That way you have access to the ServletContext via HttpServletRequest.getServletContext() from any of its methods.

kumaran L

unread,
Jul 5, 2023, 8:28:31 AM7/5/23
to WildFly
Thanks for the reply. Switching to Jakarta EE security would require us to implement  HttpAuthenticationMechanism  and IdentityStore. We already have JAAS login modules that we consume via  jaas-realm configuration in Elytron susbsytem.  If I am not wrong, moving to Jakarta EE security would require us to migrate existing JAAS login modules to appropriate IdentityStore implementation. I am not sure how to bridge  HttpAuthenticationMechanism  implementation with  jaas-realms so that I don't have to implement IdentityStore. The wildfly documentation https://docs.wildfly.org/26/WildFly_Elytron_Security.html#Elytron_and_Java_EE_Security doesn't talk much about it including remote EJB authentication. 

Basically, we need access to HttpservletRequest,  HttpservletResponse and ServletContext object in  Elytron's  HttpServerAuthenticationMechanism. Its too abstract to do any custom implementation. Is there are an option to get access to these objects?

Regards,
Kumaran




Paul Ferraro

unread,
Jul 6, 2023, 7:28:17 AM7/6/23
to WildFly
I see.  How about using HttpServerRequest.getScope(Scope.EXCHANGE), which, I think, should allow you access to objects attached to Undertow's HttpServerExchange.

kumaran L

unread,
Jul 6, 2023, 2:41:11 PM7/6/23
to WildFly
I did try  HttpServerRequest.getScope(Scope.EXCHANGE)  but I can only get request attributes from this scope. Here's how the underlying code looks like

private static HttpScope requestScope(HttpServerExchange exchange) {
        ServletRequestContext servletRequestContext = (ServletRequestContext)exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
        if (servletRequestContext != null) {
            final ServletRequest servletRequest = servletRequestContext.getServletRequest();
            return new HttpScope() {
                public boolean supportsAttachments() {
                    return true;
                }

                public void setAttachment(String key, Object value) {
                    servletRequest.setAttribute(key, value);
                }

                public Object getAttachment(String key) {
                    return servletRequest.getAttribute(key);
                }
            };
        } else {
            return null;
        }
    })

It would have been ideal if we had access to ServletRequestContext object via  getAttachment(String key) method of HttpScope.


Paul Ferraro

unread,
Jul 6, 2023, 5:06:16 PM7/6/23
to WildFly
You should be able to use a servlet filter to attach the ServletContext as a request attribute, so that it is available to Scope.EXCHANGE.
e.g.
public class ServletContextAttachmentFilter implements jakarta.servlet.Filter {
    @Override
    public void doFilter​(ServletRequest request, ServletResponse response, FilterChain chain) {
        request.setAttribute(ServletContext.class.getName(), request.getServletContext());
        chain.doFilter(request, response);

Sayantan Ganguly

unread,
Dec 16, 2024, 11:31:24 PM12/16/24
to WildFly
Hi Paul,

I am setting the attribute in one of the custom handlers and trying to get the exhange object from the HttpServerRequest that is passed to evaluateRequest().

The custom handler is setting the ServletContext but I am not able to find a way to get a handle to this in evaluateRequest() from HttpServerRequest.

Custom Handler:

ServletRequestContext context = (ServletRequestContext)httpServerExchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY);
         if(context != null) {
             ServletRequest request = context.getServletRequest();
             if(request != null) {
                 request.setAttribute(ServletContext.class.getName(), request.getServletContext());
             }
         }

evaluateRequest() :

HttpScope exchange = request.getScope(Scope.EXCHANGE);

I can see the exchange object has the Undertow's HttpServerExchange but I am unable to get a handle to this. Is there any documentation on how to get the  HttpServerExchange  object?

Thanks,
Sayantan

Sayantan Ganguly

unread,
Dec 17, 2024, 10:59:10 AM12/17/24
to WildFly, darran.l...@jboss.com
Any pointers are highly appreciated!! 

--
You received this message because you are subscribed to the Google Groups "WildFly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wildfly+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/wildfly/7a40b79f-2eb9-47ce-bef0-903e754ce63dn%40googlegroups.com.

Paul Ferraro

unread,
Jan 9, 2025, 4:15:30 PMJan 9
to WildFly
"Basically, we need access to HttpservletRequest,  HttpservletResponse and ServletContext object in  Elytron's  HttpServerAuthenticationMechanism. Its too abstract to do any custom implementation. Is there are an option to get access to these objects?"

Provided that you have the ServletFilter in place (that I described earlier) then any servlet objects required by your authentication mechanism can be made available as an attachment to the exchange scope (which exposes any request attributes as an attachment).
e.g.
public class ExchangeScopeAttachmentFilter implements jakarta.servlet.Filter {

    @Override
    public void doFilter​(ServletRequest request, ServletResponse response, FilterChain chain) {
        request.setAttribute(ServletRequest.class.getName(), request);
        request.setAttribute(ServletResponse.class.getName(), response);
        chain.doFilter(request, response);
    }
}

You can then access the servlet request/response objects as exchange scope attachments in your HttpServetAuthenticationMechanism:
e.g.
public void evaluateRequest(HttpServetRequest request) {
    HttpScope scope = request.getScope(Scope.EXCHANGE);
    HttpServetRequest req = scope.getAttachment(ServletRequest.class.getName(), HttpServletRequest.class);
    HttpServetResponse resp = scope.getAttachment(ServletResponse.class.getName(), HttpServletReponse.class);
    ServletContext context = req.getServletContext();
    // ...
}

Paul
Reply all
Reply to author
Forward
0 new messages