【问题标题】:Setting request Header in server before Authentication Happens in Keycloak在 Keycloak 中进行身份验证之前在服务器中设置请求标头
【发布时间】:2019-03-04 05:43:15
【问题描述】:

我正在使用基于 keycloak 标头的身份验证来保护 REST API。 我想在认证发生之前设置一个请求头字段(基本上是keycloak Autharization Header)。

这里解释了另一个方法:How to get javax.servlet.Filter called before Keycloak Authentication

在这次尝试中,我尝试调用覆盖的HeaderBasedKeycloakConfigResolver's 解析方法,并在调整web.xml 之后。我可以注意到它可以在身份验证发生之前调用。我还读取了一些请求标头值,但没有设置器将请求标头设置到那里(到org.keycloak.adapters.spi.HttpFacade.Request)。

寻找在 Keycloak Auth 以这种或其他方式发生之前设置请求标头的提示?

  • Key claok 版本: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>

【问题讨论】:

  • 你在你的应用程序中使用了任何类型的 keycloak 适配器吗? before authentication happens 是什么意思?适配器中永远不会发生身份验证,所发生的是应用程序检查正在发送的授权标头的有效性。如果您输入错误或没有,您只会被重定向到 keycloak 登录页面。
  • @XtremeBiker,是的,在我的实际问题中,我想在 keycloak 身份验证发生之前在服务器上附加 keycloak 授权承载令牌(通过 keycloak 令牌交换 API 检索)。首先我尝试了 seevelt 过滤器。但它在 keycloak 身份验证发生后调用。在这里,我可以在进行身份验证之前在 KeycloakConfigResolver 处接听电话。但是这里没有办法设置标题。我在这里详细描述了这个问题:stackoverflow.com/questions/51387730/….

标签: java rest security keycloak wildfly-10


【解决方案1】:

当您在配置中使用安全约束时,您可以这样做:

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) {

        }

    }
}

我以前没有使用过基于 xml 的配置,但是在 Java 配置中,我使用过 ConstraintSecurityHandler 有点像这样:

    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);

编辑:

我的回答是基于 ConstraintSecurityHandler 在调试堆栈跟踪中的 keycloak 身份验证处理程序之前出现的事实。

【讨论】:

    猜你喜欢
    • 2021-04-26
    • 2015-04-09
    • 1970-01-01
    • 2020-01-29
    • 2016-04-04
    • 2011-06-28
    • 2018-02-16
    • 1970-01-01
    • 2021-11-20
    相关资源
    最近更新 更多