1

我已经设置 Wildfly 以使用 OAUTHBEARER 身份验证机制在我的服务器和桌面应用程序之间进行远程 JNDI EJB 查找,并且效果很好。

但是,我还想设置一个简单的基于 .properties 文件的身份验证方法,以便在没有令牌的情况下与服务器进行通信以便能够请求一个,或者访问有关 keycloak 身份验证服务器的信息,因为我不想将其硬编码到我的客户端中应用程序,我似乎无法使其工作。无论我做什么,服务器都会拒绝我的身份验证尝试。

我试图访问预身份验证 bean 的示例代码如下所示:

private static PreAuth lookUpPreAuthBean() throws NamingException 
{
    final Properties jndiProperties = new Properties();
            
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
    jndiProperties.put(Context.PROVIDER_URL,"http-remoting://localhost:8080");
            
    jndiProperties.put(Context.SECURITY_PRINCIPAL, "test");
    jndiProperties.put(Context.SECURITY_CREDENTIALS, "test");
    
    final Context initialContext = new InitialContext(jndiProperties);

    return (PreAuth) initialContext.lookup("ejb:server/server-ejb/PreAuthImpl!co.my.package.server.PreAuth");
}

这是我得到的堆栈跟踪:

    Suppressed: javax.security.sasl.SaslException: ELY05019: No token was given
            at org.wildfly.security.mechanism.oauth2.OAuth2Client.getInitialResponse(OAuth2Client.java:66)
            at org.wildfly.security.sasl.oauth2.OAuth2SaslClient.evaluateMessage(OAuth2SaslClient.java:62)
            at org.wildfly.security.sasl.util.AbstractSaslParticipant.evaluateMessage(AbstractSaslParticipant.java:225)
            at org.wildfly.security.sasl.util.AbstractSaslClient.evaluateChallenge(AbstractSaslClient.java:98)
            at org.wildfly.security.sasl.util.AbstractDelegatingSaslClient.evaluateChallenge(AbstractDelegatingSaslClient.java:54)
            at org.wildfly.security.sasl.util.PrivilegedSaslClient.lambda$evaluateChallenge$0(PrivilegedSaslClient.java:55)
            at java.base/java.security.AccessController.doPrivileged(Native Method)
            at org.wildfly.security.sasl.util.PrivilegedSaslClient.evaluateChallenge(PrivilegedSaslClient.java:55)
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.lambda$handleEvent$1(ClientConnectionOpenListener.java:459)
            at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:991)
            at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
            at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
            at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
            at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
            at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
            at java.base/java.lang.Thread.run(Thread.java:829)
        Suppressed: javax.security.sasl.SaslException: DIGEST-MD5: Server rejected authentication
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:760)
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:602)
            at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
            at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
            at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
            at org.xnio.nio.WorkerThread.run(WorkerThread.java:591)

如果我要提供令牌,则承载机制有效,似乎由于某种原因其他机制没有进行身份验证

以下是我修改的 Wildfly 24 Standalone.xml 中的部分:

EJB 子系统:

...
<default-security-domain value="other"/>
<application-security-domains>
    <application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
...

Elytron 子系统:

  • 我想使用 PreAuthRealm 进行简单的身份验证。
<security-domains>
    <security-domain name="ApplicationDomain" default-realm="JWTRealm" permission-mapper="default-permission-mapper">
        <realm name="JWTRealm" role-decoder="jwt-to-roles"/>
        <realm name="PreAuthRealm" role-decoder="groups-to-roles"/>
    </security-domain>
...
<\security-domains>
  • 我想使用 application-users.properties 文件来存储用户名和密码,这些凭据是通过 add-user.sh 脚本添加到存储中的
<security-realms>
    <identity-realm name="local" identity="$local"/>
    <properties-realm name="PreAuthRealm">
        <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="PreAuthRealm"/>
        <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
    </properties-realm>
    <token-realm name="JWTRealm" principal-claim="*my claim*">
        <jwt issuer="*my issuer*" audience="account">
           <key kid="*my key id*" public-key="*my public key*"/>
        </jwt>
    </token-realm>
</security-realms>
  • sasl 身份验证工厂设置:
 <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
    <mechanism-configuration>
        <mechanism mechanism-name="OAUTHBEARER">
            <mechanism-realm realm-name="JWTRealm"/>
        </mechanism>
        <mechanism mechanism-name="DIGEST-MD5">
            <mechanism-realm realm-name="PreAuthRealm"/>
        </mechanism>   
    </mechanism-configuration>
</sasl-authentication-factory>

远程子系统:

<subsystem xmlns="urn:jboss:domain:remoting:4.0">
    <http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
</subsystem>

奇怪的是,如果我sasl-authentication-factory="application-sasl-authentication"从 Remoting 子系统中删除,并放回原来security-realm="ApplicationRealm"的上述代码运行,它实际上从 .properties 文件中对我进行身份验证,但是当然承载令牌部分将不起作用,这是整点。

我在这里的设置缺少什么?我想达到什么目标?

4

1 回答 1

0

不是解决方案,而是解决方法。"PreAuthRealm"设法通过不命名领域而是将其命名为 default来使其工作"ApplicationRealm",并且无论出于何种原因将此领域设置为安全域中的默认领域,这和 JWT 领域都可以工作。设置"JWTRealm"为默认值只会使 JWT 领域工作。

于 2021-09-28T11:52:37.793 回答