Setting request Header in server before Authentication Happens in Keycloak

℡╲_俬逩灬. 提交于 2019-12-11 15:26:10

问题


I'm using keycloak header based authentication to secure a REST API. There I want set a request header field (basically keycloak Autharization Header) before authication happes.

Another appocach for this is exlained here : How to get javax.servlet.Filter called before Keycloak Authentication

In this try I tried to call the overriden HeaderBasedKeycloakConfigResolver's resolve method and after tempering the web.xml. I could note that it can be called before the authentication happens. I read some request header values also but there is no setter to set the request headers to there (to org.keycloak.adapters.spi.HttpFacade.Request).

Looking for a hint on setting a Request Header before Keycloak Auth happens in this way or another?

  • Key claok version : 3.1.0.Final

HeaderBasedKeycloakConfigResolver.java

public class HeaderBasedKeycloakConfigResolver implements KeycloakConfigResolver {

    @Override
    public KeycloakDeployment resolve(Request request) {

        String uri = request.getURI();
        logger.info("resolve().uri : " + uri);

        String auth_key = request.getHeader("auth_key");
        logger.info("resolve().auth_key : " + auth_key);

        request.setHeader("Autherization","<auth value>"); // there's no this like setter

        KeycloakDeployment deployment = cache.get(applicationId);
        --build deployment using the keycloak.json"

        return deployment;
    }

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">

    <!-- more security-constraint -->

    <!-- keycloak -->

    <context-param>
        <param-name>keycloak.config.resolver</param-name>
        <param-value>package.to.class.HeaderBasedKeycloakConfigResolver</param-value>
    </context-param>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>REST endpoints</web-resource-name>
            <url-pattern>/ep-name/resource-name</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>resource-name</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- more security-constraint -->
    <!-- more security-constraint -->
    <!-- more security-constraint -->

     <login-config>
        <auth-method>KEYCLOAK</auth-method>
        <realm-name>realm-name</realm-name>
    </login-config>

    <security-role>
        <role-name>role-name-for-resource-1</role-name>
        <role-name>role-name-for-resource-2</role-name>
        <!-- more security-role -->
        <!-- more security-role -->
        <!-- more security-role -->
    </security-role>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>

    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/resource-path/*</url-pattern>
    </servlet-mapping>

</web-app>

回答1:


As you are using security constraints in your config, you can do this:

public class CustomConstraintSecurityHandler extends ConstraintSecurityHandler{

    @Override
    public void handle(String pathInContext, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException{

        try {
            // change the request
            super.handle(pathInContext, baseRequest, request, response);            
        }catch(Exception e) {

        }

    }
}

I have not used xml based config previously, but in Java config, I had used ConstraintSecurityHandler somewhat like this:

    ContextHandlerCollection contexts = new ContextHandlerCollection();
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY );
KeycloakJettyAuthenticator kcAuthenticator = // set keycloak through JSON
    CustomConstraintSecurityHandler securityHandler = new CustomConstraintSecurityHandler();
    ConstraintMapping constraintMapping = new ConstraintMapping();
    constraintMapping.setPathSpec("/*");                
    Constraint constraint = new Constraint();           
    constraint.setAuthenticate(true);
    constraint.setRoles(new String[]{"**"});
    constraintMapping.setConstraint(constraint);                
    securityHandler.addConstraintMapping(constraintMapping);                            
    securityHandler.setAuthenticator(kcAuthenticator);
    context.setSecurityHandler(securityHandler);

EDIT:

My answer is based on the fact that ConstraintSecurityHandler comes before keycloak authentication handler in the debug stack trace.



来源:https://stackoverflow.com/questions/52551723/setting-request-header-in-server-before-authentication-happens-in-keycloak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!