ARTICLE AD BOX
We are migrating from WildFly 24 to 38, and also implementing OIDC with Keycloak. We are deploying an EAR with multiple EJB and WAR subdeployments.
If I call an EJB via remoting from our desktop application, everything works, security context is created properly, and injecting EJB beans from an another subdeployment also work, security context propagate to all other EJB subdeployments.
The issue is, when I hit a REST endpoint from a browser into one of my WARs, the security context is correct for that WAR, ctx.getCallerPrincipal().getName() returns my logged in user, but if I inject an EJB from an another subdeployment, in those beans ctx the caller principal is anonymous.
Everything seems to be wired correctly in the standalone.xml:
EJB3 subsystem:
<application-security-domains> <application-security-domain name="mySecurityDomain" security-domain="ApplicationDomain"/> </application-security-domains>elytron:community subsystem:
<security-domains> <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper"> <realm name="ApplicationRealm" role-decoder="groups-to-roles"/> <realm name="JWTRealm" role-decoder="jwt-public-client-roles"/> </security-domain> ....Here the JWT realm works propery for remoting calls
In elytron-oidc-client subsystem I have all my WARs like so:
<secure-deployment name="com.my.project.war"> <realm>my-keycloak-realm</realm> <resource>my-keycloak-client</resource> <use-resource-role-mappings>true</use-resource-role-mappings> <auth-server-url>https://mykeycloak.com</auth-server-url> <ssl-required>NONE</ssl-required> <principal-attribute>preferred_username</principal-attribute> <verify-token-audience>true</verify-token-audience> <credential name="secret" secret="my-secret"/> </secure-deployment>In the undertow:community subsystem:
<application-security-domains> <application-security-domain name="mySecurityDomain" security-domain="ApplicationDomain"/> </application-security-domains>Undertow has this in the header tag: <subsystem ... default-security domain="mySecurityDomain">
jboss-ejb3.xml in all of the EJBs META_INF:
<?xml version="1.0" encoding="UTF-8"?> <jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" version="3.2"> <assembly-descriptor> <s:security xmlns:s="urn:security:1.1"> <ejb-name>*</ejb-name> <s:security-domain>mySecurityDomain</s:security-domain> </s:security> </assembly-descriptor> </jboss:ejb-jar>Lasty, in the WARs WEB-INF the jboss-web.xml:
<jboss-web> <security-domain>mySecurityDomain</security-domain> </jboss-web>When I read the undertow resoruce with the wildfly CLI tool i get the following output:
[standalone@localhost:29990 /] /subsystem=undertow:read-resource(recursive=true) { "outcome" => "success", "result" => { "default-security-domain" => "mySecurityDomain", "default-server" => "default-server", "default-servlet-container" => "default", "default-virtual-host" => "default-host", "instance-id" => expression "${jboss.node.name}", "obfuscate-session-route" => false, "statistics-enabled" => expression "${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}", "application-security-domain" => {"mySecurityDomain" => { "enable-jacc" => false, "enable-jaspi" => true, "http-authentication-factory" => undefined, "integrated-jaspi" => true, "override-deployment-config" => false, "security-domain" => "ApplicationDomain", "setting" => undefined }}, "buffer-cache" => {"default" => { "buffer-size" => 1024, "buffers-per-region" => 1024, "max-regions" => 10 }}, "byte-buffer-pool" => {"default" => { "buffer-size" => undefined, "direct" => undefined, "leak-detection-percent" => 0, "max-pool-size" => undefined, "thread-local-cache-size" => 12 }}, "configuration" => { "filter" => { "custom-filter" => undefined, "error-page" => undefined, "expression-filter" => undefined, "gzip" => undefined, "mod-cluster" => undefined, "request-limit" => undefined, "response-header" => undefined, "rewrite" => undefined }, "handler" => { "file" => undefined, "reverse-proxy" => undefined } }, "server" => {"default-server" => { "default-host" => "default-host", "servlet-container" => "default", "ajp-listener" => undefined, "host" => {"default-host" => { "alias" => ["localhost"], "default-response-code" => 404, "default-web-module" => "ROOT.war", "disable-console-redirect" => false, "queue-requests-on-start" => true, "filter-ref" => undefined, "location" => undefined, "setting" => { "access-log" => { "directory" => "access-log", "extended" => false, "pattern" => "%h %l %u %t \"%r\" %s %b", "predicate" => undefined, "prefix" => "access.", "relative-to" => undefined, "rotate" => true, "suffix" => ".log", "use-server-log" => false, "worker" => "default" }, "http-invoker" => { "http-authentication-factory" => "application-http-authentication", "path" => "wildfly-services", "security-realm" => undefined } } }}, "http-listener" => {"default" => { "allow-encoded-slash" => false, "allow-equals-in-cookie-value" => false, "allow-unescaped-characters-in-url" => false, "always-set-keep-alive" => true, "buffer-pipelined-data" => false, "buffer-pool" => "default", "certificate-forwarding" => false, "decode-url" => true, "disallowed-methods" => ["TRACE"], "enable-http2" => true, "enabled" => true, "http2-enable-push" => true, "http2-header-table-size" => 4096, "http2-initial-window-size" => 65535, "http2-max-concurrent-streams" => undefined, "http2-max-frame-size" => 16384, "http2-max-header-list-size" => undefined, "max-buffered-request-size" => 16384, "max-connections" => undefined, "max-cookies" => 200, "max-header-size" => 1048576, "max-headers" => 200, "max-parameters" => 1000, "max-post-size" => 10485760L, "no-request-timeout" => 60000, "proxy-address-forwarding" => false, "proxy-protocol" => false, "read-timeout" => 90000, "receive-buffer" => undefined, "record-request-start-time" => false, "redirect-socket" => "http", "request-parse-timeout" => undefined, "require-host-http11" => false, "resolve-peer-address" => false, "rfc6265-cookie-validation" => false, "secure" => false, "send-buffer" => undefined, "socket-binding" => "http", "tcp-backlog" => 10000, "tcp-keep-alive" => undefined, "url-charset" => "UTF-8", "worker" => "default", "write-timeout" => 90000 }}, "https-listener" => undefined }}, "servlet-container" => {"default" => { "allow-non-standard-wrappers" => false, "allow-orphan-session" => false, "default-buffer-cache" => "default", "default-cookie-version" => 0, "default-encoding" => undefined, "default-session-timeout" => 30, "directory-listing" => undefined, "disable-caching-for-secured-pages" => true, "disable-file-watch-service" => false, "disable-session-id-reuse" => false, "eager-filter-initialization" => false, "file-cache-max-file-size" => 10485760, "file-cache-metadata-size" => 100, "file-cache-time-to-live" => undefined, "ignore-flush" => false, "max-sessions" => undefined, "preserve-path-on-forward" => false, "proactive-authentication" => true, "session-id-length" => 30, "stack-trace-on-error" => "local-only", "use-listener-encoding" => false, "mime-mapping" => undefined, "setting" => { "jsp" => { "check-interval" => 0, "development" => false, "disabled" => false, "display-source-fragment" => true, "dump-smap" => false, "error-on-use-bean-invalid-class-attribute" => false, "generate-strings-as-char-arrays" => false, "java-encoding" => "UTF8", "keep-generated" => true, "mapped-file" => true, "modification-test-interval" => 4, "optimize-scriptlets" => false, "recompile-on-fail" => false, "scratch-dir" => undefined, "smap" => true, "source-vm" => "1.8", "tag-pooling" => true, "target-vm" => "1.8", "trim-spaces" => false, "x-powered-by" => true }, "websockets" => { "buffer-pool" => "default", "deflater-level" => 0, "dispatch-to-worker" => true, "per-message-deflate" => false, "worker" => "default" } }, "welcome-file" => undefined }} } }My understanding is that both the EJB3 subsystem and the Undertow subsystem hands authentication and authorization to Elytron, which creates the security context for ApplicationDomain, and both EJB3 and Undertow are connected to it.
There are no restriction in any web.xml or application.xml anywhere
What am I missing?
