OIDC for JEE with pac4j

huangapple go评论63阅读模式
英文:

OIDC for JEE with pac4j

问题

I tried a lot of things for pac4j but I'm feeling a bit lost.
我尝试了很多方法来使用 pac4j,但感到有些困惑。

I just want to use a definition of a code authorization flow for OIDC and then use the fetched and validated access token and ID token for other requests started from my web app.
我只想使用 OIDC 的代码授权流程定义,然后使用从我的 Web 应用程序启动的其他请求中获取和验证的访问令牌和 ID 令牌。

But in the examples, I seem only to find examples regarding the usage of Spring and other more abstracted frameworks.
但在示例中,我似乎只找到了关于使用Spring和其他更抽象框架的示例。

I found https://www.pac4j.org/docs/callback-endpoint.html, but this seems to be for 6.0. I can't use that because I must not use Jakarta; I have to use javax.
我找到了https://www.pac4j.org/docs/callback-endpoint.html,但这似乎是针对版本6.0的。我不能使用它,因为我不能使用 Jakarta,我必须使用 javax。

I managed to configure the initial redirect but now I'm stuck at the callback. It doesn't use the retrieved data or put the tokens into session.
我成功配置了初始重定向,但现在在回调时卡住了。它不使用检索到的数据,也不将令牌放入会话中。

Are there anywhere examples or unit tests I might derive how to configure, combine, and call the different parts?
是否有任何示例或单元测试,我可以从中了解如何配置、组合和调用不同的部分?

I'm using build.gradle with dependencies:
我正在使用 build.gradle 文件和依赖项:

    // https://mvnrepository.com/artifact/org.pac4j/jee-pac4j
    implementation 'org.pac4j:jee-pac4j:6.1.0'
    // https://mvnrepository.com/artifact/org.pac4j/pac4j-core
    implementation 'org.pac4j:pac4j-core:5.7.0'
    implementation 'org.pac4j:pac4j-oidc:5.7.0'
    implementation 'org.pac4j:pac4j-javaee:5.7.0'
...
}

Unfortunately, I see a class cast exception when the authentication returns from the IDP:
不幸的是,当身份验证返回时,我看到一个类转换异常:

	java.lang.ClassCastException: class org.pac4j.jee.context.JEEContext cannot be cast to class org.pac4j.core.context.JEEContext (org.pac4j.jee.context.JEEContext and org.pac4j.core.context.JEEContext are in the unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @5ababd21)
		at org.pac4j.core.http.adapter.JEEHttpActionAdapter.adapt(JEEHttpActionAdapter.java:27)
		at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:94)
		at com.example.sampleweb.pac4j.CustomCallbackFilter.internalFilter(CustomCallbackFilter.java:75)

which points to callbackLogic.perform(context, new JEESessionStoreFactory().newSessionStore(), getConfig(), JEEHttpActionAdapter.INSTANCE, "/", true, getDefaultClient()); from my CustomCallbackFilter.java:

指向 callbackLogic.perform(context, new JEESessionStoreFactory().newSessionStore(), getConfig(), JEEHttpActionAdapter.INSTANCE, "/", true, getDefaultClient()); 这段代码在我的 CustomCallbackFilter.java 中:


import org.aeonbits.owner.ConfigFactory;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.jee.context.JEEContext;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.engine.DefaultCallbackLogic;
import org.pac4j.core.http.adapter.JEEHttpActionAdapter;
import org.pac4j.jee.context.session.JEESessionStoreFactory;
import org.pac4j.jee.filter.CallbackFilter;
import org.pac4j.oidc.config.OidcConfiguration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
import java.util.logging.Logger;

@WebFilter(urlPatterns = "/callback")
public class CustomCallbackFilter extends CallbackFilter {
    private static final Logger LOGGER = Logger.getLogger(CustomCallbackFilter.class.getName());
    private DefaultCallbackLogic callbackLogic;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        LOGGER.severe("init started");
        super.init(filterConfig);

        EisConfiguration eisConfiguration = ConfigFactory.create(EisConfiguration.class);
        CustomOidcIdpConfigurationFactory idpConfigurationFactory = new CustomOidcIdpConfigurationFactory(eisConfiguration, "app1");
        OidcConfiguration oidcConfiguration = idpConfigurationFactory.createOidcConfiguration();
        Config config =
                //new Config();
                getSharedConfig();
        LOGGER.severe("init using config " + config);

        String client = getDefaultClient();
        LOGGER.severe("init using client " + client);

        callbackLogic = new DefaultCallbackLogic();
        LOGGER.severe("init using callbackLogic " + callbackLogic);
        setCallbackLogic(callbackLogic);
        setConfig(config);
        LOGGER.severe("init finished");
        super.init(filterConfig);
    }

    @Override
    protected void internalFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        LOGGER.severe("callback internalFilter started");

        LOGGER.severe("callback internalFilter callbackLogic " + callbackLogic);

        WebContext context = new JEEContext(request, response);
        Config config = getSharedConfig();
        LOGGER.severe("callback internalFilter Config " + config);
        LOGGER.severe("callback internalFilter Config " + config.getSessionStoreFactory());

        String defaultClient = getDefaultClient();
        LOGGER.severe("callback internalFilter defaultClient " + defaultClient);

        Clients clients = config.getClients();
        LOGGER.severe("callback internalFilter

<details>
<summary>英文:</summary>

I tried a lot of things for pac4j but I&#39;m feeling a bit lost.

I just want to use a definition of an code authorisation flow for OIDC and then use the fetched and validated access token and id token for other requests started from my webapp.
But in the examples I seem only to find examples regarding usage of Spring and other more abstracted frameworks.

I found https://www.pac4j.org/docs/callback-endpoint.html, but this seems to be for 6.0. I can&#39;t use that, because I must not use Jakarta, I have to use javax.

I managed to configure the initial redirect but now I&#39;m stuck at the callback. It doesn&#39;t use the retrieved data or put the tokens into session.

Are there anywhere examples or unit tests I might derive how to configure, combine and call the different parts?



I&#39;m using build.gradle with dependencies:

dependencies {
// https://mvnrepository.com/artifact/org.pac4j/jee-pac4j
implementation 'org.pac4j:jee-pac4j:6.1.0'
// https://mvnrepository.com/artifact/org.pac4j/pac4j-core
implementation 'org.pac4j:pac4j-core:5.7.0'
implementation 'org.pac4j:pac4j-oidc:5.7.0'
implementation 'org.pac4j:pac4j-javaee:5.7.0'
...
}


Unfortunately I see an class cast exception, when the authentication returns from IDP:


08-Apr-2023 17:12:09.751 SEVERE [http-nio-8080-exec-8] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [default] in context with path [/Gradle___com_example___pac4j_1_0_SNAPSHOT_war] threw exception
java.lang.ClassCastException: class org.pac4j.jee.context.JEEContext cannot be cast to class org.pac4j.core.context.JEEContext (org.pac4j.jee.context.JEEContext and org.pac4j.core.context.JEEContext are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @5ababd21)
at org.pac4j.core.http.adapter.JEEHttpActionAdapter.adapt(JEEHttpActionAdapter.java:27)
at org.pac4j.core.engine.DefaultCallbackLogic.perform(DefaultCallbackLogic.java:94)
at com.example.sampleweb.pac4j.CustomCallbackFilter.internalFilter(CustomCallbackFilter.java:75)


which points to `callbackLogic.perform(context, new JEESessionStoreFactory().newSessionStore(), getConfig(), JEEHttpActionAdapter.INSTANCE, &quot;/&quot;, true, getDefaultClient());`

from my CustomCallbackFilter.java:

package com.example.sampleweb.pac4j;

import org.aeonbits.owner.ConfigFactory;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.jee.context.JEEContext;
import org.pac4j.core.context.WebContext;
import org.pac4j.core.engine.DefaultCallbackLogic;
import org.pac4j.core.http.adapter.JEEHttpActionAdapter;
import org.pac4j.jee.context.session.JEESessionStoreFactory;
import org.pac4j.jee.filter.CallbackFilter;
import org.pac4j.oidc.config.OidcConfiguration;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Optional;
import java.util.logging.Logger;

@WebFilter(urlPatterns = "/callback")
public class CustomCallbackFilter extends CallbackFilter {
private static final Logger LOGGER = Logger.getLogger(CustomCallbackFilter.class.getName());
private DefaultCallbackLogic callbackLogic;

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    LOGGER.severe(&quot;init started&quot;);
    super.init(filterConfig);

    EisConfiguration eisConfiguration = ConfigFactory.create(EisConfiguration.class);
    CustomOidcIdpConfigurationFactory idpConfigurationFactory = new CustomOidcIdpConfigurationFactory(eisConfiguration, &quot;app1&quot;);
    OidcConfiguration oidcConfiguration = idpConfigurationFactory.createOidcConfiguration();
    Config config =
            //new Config();
            getSharedConfig();
    LOGGER.severe(&quot;init using config &quot; + config);

    String client = getDefaultClient();
    LOGGER.severe(&quot;init using client &quot; + client);

    callbackLogic = new DefaultCallbackLogic();
    LOGGER.severe(&quot;init using callbackLogic &quot; + callbackLogic);
    setCallbackLogic(callbackLogic);
    setConfig(config);
    LOGGER.severe(&quot;init finished&quot;);
    super.init(filterConfig);
}

@Override
protected void internalFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
    LOGGER.severe(&quot;callback internalFilter started&quot;);

    LOGGER.severe(&quot;callback internalFilter callbackLogic &quot; + callbackLogic);

    WebContext context = new JEEContext(request, response);
    Config config = getSharedConfig();
    LOGGER.severe(&quot;callback internalFilter Config &quot; + config);
    LOGGER.severe(&quot;callback internalFilter Config &quot; + config.getSessionStoreFactory());

    String defaultClient = getDefaultClient();
    LOGGER.severe(&quot;callback internalFilter defaultClient &quot; + defaultClient);

    Clients clients = config.getClients();
    LOGGER.severe(&quot;callback internalFilter clients &quot; + clients);
    Optional&lt;Client&gt; oidcClient = clients.findClient(&quot;IDP_CLIENT&quot;);
    LOGGER.severe(&quot;callback internalFilter oidcClient &quot; + oidcClient);

    LOGGER.severe(&quot;callback internalFilter perform &quot; + callbackLogic);
    LOGGER.severe(&quot;callback internalFilter state &quot; + request.getParameter(&quot;state&quot;));

    org.pac4j.core.context.JEEContext webContext = new org.pac4j.core.context.JEEContext(request, response);
    callbackLogic.perform(context, new JEESessionStoreFactory().newSessionStore(), getConfig(), JEEHttpActionAdapter.INSTANCE, &quot;/&quot;, true, getDefaultClient());

    //dcl.perform(context, config.getSessionStore(), config, config.getHttpActionAdapter(), getDefaultUrl(), config.c);
    //super.internalFilter(request, response, chain);
    LOGGER.severe(&quot;callback internalFilter finished&quot;);
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    LOGGER.severe(&quot;callback filter started&quot;);
    //super.doFilter(request, response, chain);
    LOGGER.severe(&quot;callback filter finished&quot;);
}

}



Looking at the server logs I print, it seems there is everything returning nicely from IDP, but the class cast is not possible because of the used JARs.
As you can see above I tried to comply with the signature of the perform method an provided request/response using the alternative JEE implementation for the call, but that doesn&#39;t work either.
However
     org.pac4j.jee.context.JEEContext;
seems to be in conflict with
    org.pac4j.core.context.JEEContext
and I don&#39;t know exactly what to do here.

Thanks for your help in advance!

Thorsten

</details>


# 答案1
**得分**: 1

如在 https://github.com/pac4j/jee-pac4j 的 README 中所述:
[![enter image description here][1]][1]

您应该使用版本为 7.1.0 的 `javaee-pac4j` 依赖,以及版本为 5.7.0 的 `pac4j-javaee`、`pac4j-core`、`pac4j-oidc` 等依赖。还需要 JDK 11。

请查看演示:https://github.com/pac4j/jee-pac4j-demo/blob/7.1.x/pom.xml(7.1.x 分支)

[1]: https://i.stack.imgur.com/89chB.png

<details>
<summary>英文:</summary>

As presented on the https://github.com/pac4j/jee-pac4j README:
[![enter image description here][1]][1]

You should use the `javaee-pac4j` dependency in version 7.1.0 as well as the `pac4j-javaee`, `pac4j-core`, `pac4j-oidc`, ... dependencies in version 5.7.0. And JDK 11.

Please take a look at the demo: https://github.com/pac4j/jee-pac4j-demo/blob/7.1.x/pom.xml (7.1.x branch)


  [1]: https://i.stack.imgur.com/89chB.png

</details>



huangapple
  • 本文由 发表于 2023年4月11日 16:13:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75983757.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定