在身份验证发生在Keycloak中之前,先在服务器中设置请求标头 [英] Setting request Header in server before Authentication Happens in Keycloak

查看:81
本文介绍了在身份验证发生在Keycloak中之前,先在服务器中设置请求标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

此处介绍了另一种解决方法:如何获取在Keycloak身份验证之前调用的javax.servlet.Filter

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

在这种尝试中,我尝试调用覆盖的HeaderBasedKeycloakConfigResolver's resolve方法,并调节了web.xml后的状态.我可以注意到,可以在身份验证发生之前调用它.我也读取了一些请求标头值,但是没有设置程序将请求标头设置到那里(org.keycloak.adapters.spi.HttpFacade.Request).

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

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

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

  • 主键版​​本: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>

推荐答案

在配置中使用安全约束时,您可以执行以下操作:

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

        }

    }
}

我以前没有使用过基于xml的配置,但是在Java配置中,我曾使用过ConstraintSecurityHandler,如下所示:

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

我的答案基于以下事实:ConstraintSecurityHandler在调试堆栈跟踪中位于密钥隐藏身份验证处理程序之前.

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

这篇关于在身份验证发生在Keycloak中之前,先在服务器中设置请求标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆