java.lang.Exception: Insufficient roles/credentials for operation - keycloak

I'm using ActiveMQ Artemis 2.16.0 and the management console is based on Hawtio. I've successfully integrated it with Keycloak (OpenID Connect) using this instructions.
Now I've upgraded to ActiveMQ Artemis 2.17.0 and it stop working. Hawtio version seems the same:
[io.hawt.jmx.JmxTreeWatcher] Welcome to Hawtio 2.11.0
Since ActiveMQ Artemis is quite easy to upgrade I can easily switch from one version to another. I did it and the logs seems to output the same:
[org.apache.activemq.artemis.core.server] AMQ221001: Apache ActiveMQ Artemis Message Broker version 2.17.0 [node1.some.domain, nodeID=bcf5b788-c0fd-11ea-9c54-0050568bf82b]
[org.apache.activemq.artemis.core.server] AMQ221053: Disallowing use of vulnerable protocol 'SSLv2Hello' on acceptor 'artemis'. See http://www.oracle.com/technetwork/topics/security/poodlecve-2014-3566-2339408.html for more details.
[io.hawt.web.plugin.HawtioPlugin] Registering plugin hawtio:type=plugin,name=activemq-branding
[org.apache.activemq.hawtio.branding.PluginContextListener] Initialized activemq-branding plugin
[io.hawt.web.plugin.HawtioPlugin] Registering plugin hawtio:type=plugin,name=artemis-plugin
[org.apache.activemq.hawtio.plugin.PluginContextListener] Initialized artemis-plugin plugin
[io.hawt.HawtioContextListener] Initialising hawtio services
[io.hawt.system.ConfigManager] Failed to look up environment context: null
[io.hawt.system.ConfigManager] Configuration will be discovered via system properties
[io.hawt.jmx.JmxTreeWatcher] Welcome to Hawtio 2.11.0
[io.hawt.system.ConfigManager] Property realm is set to value hawtio
[io.hawt.system.ConfigManager] Property role is set to value null
[io.hawt.system.ConfigManager] Property roles is set to value amq,artemis_admin,artemis_manager,artemis_viewer
[io.hawt.system.ConfigManager] Property rolePrincipalClasses is set to value org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.ConfigManager] Property authenticationEnabled is set to value true
[io.hawt.system.ConfigManager] Property noCredentials401 is set to value false
[io.hawt.system.ConfigManager] Property keycloakEnabled is set to value true
[io.hawt.system.ConfigManager] Property authenticationContainerDiscoveryClasses is set to value io.hawt.web.tomcat.TomcatAuthenticationContainerDiscovery
[io.hawt.web.tomcat.TomcatAuthenticationContainerDiscovery] Realm explicit configured hawtio. Apache Tomcat userdata authentication integration not in use.
[io.hawt.web.auth.AuthenticationConfiguration] Starting hawtio authentication filter, JAAS realm: "hawtio" authorized role(s): "amq,artemis_admin,artemis_manager,artemis_viewer" role principal classes: "org.keycloak.adapters.jaas.RolePrincipal"
[io.hawt.system.ConfigManager] Property keycloakClientConfig is set to value file:/opt/artemis-broker/etc/keycloak-client-hawtio.json
[io.hawt.web.filters.ContentSecurityPolicyFilter] Found Keycloak URL: https://auth.some.domain/auth
[io.hawt.system.ConfigManager] Property http.strictTransportSecurity is set to value null
[io.hawt.web.filters.PublicKeyPinningFilter] HTTP Strict Transport Security is disabled
[io.hawt.system.ConfigManager] Property http.publicKeyPins is set to value null
[io.hawt.web.filters.PublicKeyPinningFilter] Public Key Pinning is disabled
[io.hawt.system.ConfigManager] Property sessionTimeout is set to value 1800
[io.hawt.system.ConfigManager] Property disableProxy is set to value false
[io.hawt.system.ConfigManager] Property proxyAllowlist is set to value localhost,
[io.hawt.system.ConfigManager] Property localAddressProbing is set to value true
[io.hawt.system.ProxyAllowlist] Probing local addresses ...
[io.hawt.system.ProxyAllowlist] Initial proxy allowlist: [localhost, 127.0.0.1, 10.3.84.148, node01.some.domain]
[io.hawt.web.servlets.JolokiaConfiguredAgentServlet] Jolokia overridden property: [key=policyLocation, value=file:/opt/artemis-broker/etc/jolokia-access.xml]
[org.apache.activemq.artemis] AMQ241001: HTTP Server started at https://0.0.0.0:8443
[org.apache.activemq.artemis] AMQ241002: Artemis Jolokia REST API available at https://0.0.0.0:8443/console/jolokia
[org.apache.activemq.artemis] AMQ241004: Artemis Console available at https://0.0.0.0:8443/console
[io.hawt.web.auth.SessionExpiryFilter] Accessing [/console/jolokia/], hawtio path is [jolokia]
[io.hawt.web.auth.AuthenticationFilter] Handling request for path /jolokia
[io.hawt.web.auth.AuthenticationFilter] Doing authentication and authorization for path /jolokia
[io.hawt.system.Authenticator] doAuthenticate[realm=hawtio, role=amq,artemis_admin,artemis_manager,artemis_viewer, rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal, configuration=null, username=myuser, password=******]
[org.keycloak.adapters.jaas.BearerTokenLoginModule] Declared options: keycloak-config-file=/export/opt/artemis-broker/etc/keycloak-server-bearer.json, role-principal-class=org.keycloak.adapters.jaas.RolePrincipal
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Using provider 'secret' for authentication of client 'artemis'
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider secret
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider jwt
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider secret-jwt
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider secret
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider jwt
[org.keycloak.adapters.authentication.ClientCredentialsProviderUtils] Loaded clientCredentialsProvider secret-jwt
[org.keycloak.adapters.KeycloakDeployment] Resolving URLs from https://auth.some.domain/auth/realms/myrealm/.well-known/openid-configuration
[org.keycloak.adapters.KeycloakDeployment] Loaded URLs from https://auth.some.domain/auth/realms/myrealm/.well-known/openid-configuration
[org.keycloak.adapters.rotation.JWKPublicKeyLocator] Realm public keys successfully retrieved for client artemis. New kids: [kkFaKnnudVd5UxaVISthQL6VgTRIKYCUGanBKIiGGZg, kyipLFJfqsg9TxC94XAXy4VahWRbDRD0F_spMHJzhzk]
[io.hawt.system.Authenticator] Looking for rolePrincipalClass: org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.KeycloakPrincipal toString: 771b46db-5e22-4318-8ef3-0ffd4b10d223
[io.hawt.system.Authenticator] principal class org.keycloak.KeycloakPrincipal doesn't match org.keycloak.adapters.jaas.RolePrincipal, continuing
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.adapters.jaas.RolePrincipal toString: amq
[io.hawt.system.Authenticator] Matched role and role principal class
[io.hawt.web.auth.SessionExpiryFilter] Accessing [/console/jolokia/], hawtio path is [jolokia]
[io.hawt.web.auth.AuthenticationFilter] Handling request for path /jolokia
[io.hawt.web.auth.AuthenticationFilter] Doing authentication and authorization for path /jolokia
[io.hawt.system.Authenticator] doAuthenticate[realm=hawtio, role=amq,artemis_admin,artemis_manager,artemis_viewer, rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal, configuration=null, username=myuser, password=******]
[org.keycloak.adapters.jaas.BearerTokenLoginModule] Declared options: keycloak-config-file=/export/opt/artemis-broker/etc/keycloak-server-bearer.json, role-principal-class=org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.Authenticator] Looking for rolePrincipalClass: org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.KeycloakPrincipal toString: 771b46db-5e22-4318-8ef3-0ffd4b10d223
[io.hawt.system.Authenticator] principal class org.keycloak.KeycloakPrincipal doesn't match org.keycloak.adapters.jaas.RolePrincipal, continuing
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.adapters.jaas.RolePrincipal toString: amq
[io.hawt.system.Authenticator] Matched role and role principal class
[io.hawt.web.auth.SessionExpiryFilter] Accessing [/console/jolokia/], hawtio path is [jolokia]
[io.hawt.web.auth.AuthenticationFilter] Handling request for path /jolokia
[io.hawt.web.auth.AuthenticationFilter] Doing authentication and authorization for path /jolokia
[io.hawt.system.Authenticator] doAuthenticate[realm=hawtio, role=amq,artemis_admin,artemis_manager,artemis_viewer, rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal, configuration=null, username=myuser, password=******]
[org.keycloak.adapters.jaas.BearerTokenLoginModule] Declared options: keycloak-config-file=/export/opt/artemis-broker/etc/keycloak-server-bearer.json, role-principal-class=org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.Authenticator] Looking for rolePrincipalClass: org.keycloak.adapters.jaas.RolePrincipal
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.KeycloakPrincipal toString: 771b46db-5e22-4318-8ef3-0ffd4b10d223
[io.hawt.system.Authenticator] principal class org.keycloak.KeycloakPrincipal doesn't match org.keycloak.adapters.jaas.RolePrincipal, continuing
[io.hawt.system.Authenticator] Checking principal, classname: org.keycloak.adapters.jaas.RolePrincipal toString: amq
[io.hawt.system.Authenticator] Matched role and role principal class
and I'm using these parameters:
-Dhawtio.authenticationEnabled=true
-Dhawtio.offline=true -Dhawtio.realm=hawtio
-Dhawtio.keycloakEnabled=true -Dhawtio.roles=amq,artemis_admin,artemis_manager,artemis_viewer
-Dhawtio.rolePrincipalClasses=org.keycloak.adapters.jaas.RolePrincipal
-Dhawtio.keycloakClientConfig=${ARTEMIS_INSTANCE_ETC_URI}keycloak-client-hawtio.json
-Dhawtio.keycloakServerConfig=${ARTEMIS_INSTANCE_ETC}/keycloak-server-bearer.json
-Djolokia.policyLocation=${ARTEMIS_INSTANCE_ETC_URI}jolokia-access.xml
and the management.xml is:
...
<role-access>
<match domain="org.apache.activemq.artemis">
<access method="list*" roles="amq,artemis_admin"/>
<access method="get*" roles="amq,artemis_admin"/>
<access method="is*" roles="amq,artemis_admin"/>
<access method="set*" roles="amq,artemis_admin"/>
<access method="*" roles="amq,artemis_admin"/>
</match>
...
But seems the role that comes from OpenID Connect doesn't match it.
Any ideas? If you need more config details I can add here.

Since ActiveMQ Artemis 2.18 the integration with third-party login modules has improved, see ARTEMIS-3168.
A good example is available at https://github.com/apache/activemq-artemis/tree/2.20.0/examples/features/standard/security-keycloak

Related

Wildfly 26.1.0 final + elytron-oidc-client + wont propagate user to EJB + user become anonymous

I am trying to upgrade from WF24 to WF26.1.0 final and migrate from the jboss:domain:keycloak module to elytron-oidc-client.
I have installed WF26.1.0 and configured elytron-oidc-client with secure-deployment to use our Keycloak server for authentication. I can log into my webpages and rest services provided by the WAR deployment, and I get the correct roles listed for my keycloak users.
Here is the log that shows when elytron-oidc-client retrieves the authenticated user and adds it to a generic security domain with the 'virtual' realm:
2022-05-01 06:46:10,652 TRACE [org.wildfly.security] (default task-4) Handling SecurityIdentityCallback: identity = SecurityIdentity{principal=testuser, securityDomain=org.wildfly.security.auth.server.SecurityDomain#3e51905b, authorizationIdentity=EMPTY, realmInfo=RealmInfo{name='virtual', securityRealm=org.wildfly.security.http.oidc.OidcSecurityRealm#796ef014}, creationTime=2022-05-01T04:46:10.651489Z}
The secure deployment look like this in stanalone-full.xml:
<subsystem xmlns="urn:wildfly:elytron-oidc-client:1.0">
<realm name="MyRealm">
<auth-server-url>https://127.0.0.1/auth/</auth-server-url>
<ssl-required>NONE</ssl-required>
<enable-cors>true</enable-cors>
<principal-attribute>preferred_username</principal-attribute>
</realm>
<secure-deployment name="farm-application-fleet-jsweb.war">
<realm>MyRealm</realm>
<resource>MyResource</resource>
<public-client>true</public-client>
</secure-deployment>
</subsystem>
When a REST service deployed in the WAR tries to connect to a EJB deployed in a different EAR then the user become "anonymous" and access is not allowed.
Here are some of my Wildfly log that shows the authenticated user become anonymous when I am calling the EJB method getAllMvaCodes declared like this:
#RolesAllowed({ "user","appuser" })
public GeneralResponse getAllMvaCodes () {....}
Instead of an correct result because my authenticated user has the correct roles, I get "is not allowed":
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Role mapping: principal [testuser] -> decoded roles [appuser, workshop, car_booking, plowing, superadmin, triplog, admin, transport, user] -> domain decoded roles [] -> realm mapped roles [appuser, workshop, car_booking, plowing, superadmin, triplog, admin, transport, user] -> domain mapped roles [appuser, workshop, car_booking, plowing, superadmin, triplog, admin, transport, user]
2022-05-01 06:46:10,651 TRACE [org.xnio.nio.selector] (default I/O-19) Selected key channel=java.nio.channels.SocketChannel[connected local=/127.0.0.1:8443 remote=/127.0.0.1:49577], selector=sun.nio.ch.KQueueSelectorImpl#db86f05, interestOps=1, readyOps=1 for java.nio.channels.SocketChannel[connected local=/127.0.0.1:8443 remote=/127.0.0.1:49577]
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Authorizing principal testuser.
2022-05-01 06:46:10,651 TRACE [org.xnio.nio.selector] (default I/O-19) Calling handleReady key 1 for java.nio.channels.SocketChannel[connected local=/127.0.0.1:8443 remote=/127.0.0.1:49577]
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Authorizing against the following attributes: [Roles] => [appuser, workshop, car_booking, plowing, superadmin, triplog, admin, transport, user]
2022-05-01 06:46:10,651 TRACE [org.xnio.listener] (default I/O-19) Invoking listener io.undertow.server.protocol.framed.AbstractFramedChannel$FrameReadListener#6a65085c on channel org.xnio.conduits.ConduitStreamSourceChannel#734aed38
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Authorizing against the following runtime attributes: [] => []
2022-05-01 06:46:10,651 TRACE [io.undertow.request.io] (default I/O-19) Invoking receive listener: io.undertow.server.protocol.http2.Http2ReceiveListener#226d75b6 - receiver: null
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Permission mapping: identity [testuser] with roles [appuser, workshop, car_booking, plowing, superadmin, triplog, admin, transport, user] implies ("org.wildfly.security.auth.permission.LoginPermission" "") = true
2022-05-01 06:46:10,651 TRACE [org.wildfly.security] (default task-4) Authorization succeed
2022-05-01 06:46:10,651 TRACE [org.xnio.listener] (default I/O-19) Invoking listener io.undertow.server.protocol.http2.Http2ReceiveListener#226d75b6 on channel Http2Channel peer /127.0.0.1:49577 local /127.0.0.1:8443[ No Receiver [] -- [] -- []
2022-05-01 06:46:10,651 ERROR [org.jboss.as.ejb3.invocation] (default task-6) WFLYEJB0034: Jakarta Enterprise Beans Invocation failed on component InvoiceBean for method public abstract no.farm.service.fleet.dto.GeneralResponse no.farm.service.fleet.ejb.InvoiceRemote.getAllMvaCodes(): javax.ejb.EJBAccessException: WFLYEJB0364: Invocation on method: public abstract no.farm.service.fleet.dto.GeneralResponse no.farm.service.fleet.ejb.InvoiceRemote.getAllMvaCodes() of bean: InvoiceBean is not allowed
Is there a way that I can configure Wildfly to propagate the user correctly from the WEB to the EJB?
The elytron-oidc-client subsystem makes use of a virtual security domain. Currently, this virtual security domain can't be referenced from other deployments.
However, the identity would get propagated to EJBs within the same deployment.

How to get cluster nodes information on Wildfly 21?

I am trying to get the cluster information (esp nodes list) with the below Application code.
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
String clusterMembers = (String) (server.getAttribute(new ObjectName("jboss.infinispan:type=CacheManager,name=\"ejb\",component=CacheManager"), "clusterMembers"));
(or)
Object obj = server.getAttribute(ObjectName.getInstance("jgroups:type=channel,cluster=\"web\""), "View");
Both are throwing InstanceNotFoundExceptions.
javax.management.InstanceNotFoundException: jgroups:type=channel,cluster="web"
2021-02-08 15:39:59,046 ERROR [stderr:71] (default task-1) javax.management.InstanceNotFoundException: jgroups:type=channel,cluster="web"
2021-02-08 15:39:59,047 ERROR [stderr:71] (default task-1) at org.jboss.as.jmx.PluggableMBeanServerImpl.findDelegate(PluggableMBeanServerImpl.java:1113)
2021-02-08 15:39:59,047 ERROR [stderr:71] (default task-1) at org.jboss.as.jmx.PluggableMBeanServerImpl.getAttribute(PluggableMBeanServerImpl.java:389)
There are a number of ways to do this. Programmatically, perhaps the simplest way is to use WildFly's clustering API. For details, see: https://github.com/wildfly/wildfly/blob/master/docs/src/main/asciidoc/_high-availability/Clustering_API.adoc#group-membership
Alternatively, you can also use WildFly's CLI to obtain cluster information.
e.g.
[standalone#embedded /] /subsystem=jgroups/channel=ee:read-attribute(name=view)
{
"outcome" => "success",
"result" => "[localhost|0] (1) [localhost]"
}
Alternatively, you can obtain cluster information using Infinispan or JGroups APIs directly.
e.g.
#Resource(lookup = "java:jboss/infinispan/cache-container/web")
private EmbeddedCacheManager manager;
#Resource(lookup = "java:jboss/jgroups/channel/default")
private JChannel channel;
public void foo() {
System.out.println(this.manager.getMembers());
System.out.println(this.channel.getView());
}
Lastly, if you prefer to go the JMX route, ensure that your WildFly configuration defines a JMX subsystem, otherwise no mbeans will be registered.
Infinispan mbeans are registered using the domain: "org.wildfly.clustering.infinispan". Make sure you are using 22.0.1.Final which includes a fix for https://issues.redhat.com/browse/WFLY-14286
Your jgroups jmx code name is almost correct - using the default configuration, each Infinispan cache manager uses a distinct ForkChannel based on a common JChannel, named "ee".

Enable REST service for CAS Apereo version cas-overlay-template-6.0

I want to enable REST service for CAS Apereo version cas-overlay-template-6.0 (on Ubuntu 16.04)
I have done following this step:
Step 1: Add compile for REST API to build.gradle file
root#ubuntu16:~/cas-overlay-template-6.0# nano build.gradle
And add two line below under dependencies clock
compile "org.apereo.cas:cas-server-support-rest:6.0.0"
compile "org.apereo.cas:cas-server-support-rest-services:6.0.0"
Step 2: clean build
root#ubuntu16:~/cas-overlay-template-6.0# ./build.sh clean
Step 3: Build source code again
root#ubuntu16:~/cas-overlay-template-6.0# ./build.sh run
But in step 3, I got error like this.
CAS is configured to accept a static list of credentials for authentication. While this is generally useful for demo purposes, it is STRONGLY recommended that you DISABLE this authentication method (by setting 'cas.authn.accept.users' to a blank value) and switch to a mode that is more suitable for production.>
2019-12-30 01:17:55,465 WARN [org.apereo.cas.config.support.authentication.AcceptUsersAuthenticationEventExecutionPlanConfiguration] - <>
2019-12-30 01:17:55,806 INFO [org.apereo.cas.config.CasPersonDirectoryConfiguration] - <Found and added static attributes [[email]] to the list of candidate attribute repositories>
2019-12-30 01:17:59,004 WARN [org.apereo.cas.web.CasWebApplicationContext] - <Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'registeredServiceResourceRestController' defined in class path resource [org/apereo/cas/support/rest/config/RestServicesConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apereo.cas.support.rest.RegisteredServiceResource]: Factory method 'registeredServiceResourceRestController' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: No attribute name is defined to enforce authorization when adding services via CAS REST APIs. This is likely due to misconfiguration in CAS settings where the attribute name definition is absent>
Where have I gone wrong?
Remove this:
compile "org.apereo.cas:cas-server-support-rest-services:6.0.0"
This module does this:
Invoke CAS to register applications into its own service registry. The REST call must be authenticated using basic authentication where credentials are authenticated and accepted by the existing CAS authentication strategy, and furthermore the authenticated principal must be authorized with a pre-configured role/attribute name and value that is designated in the CAS configuration via the CAS properties. The body of the request must be the service definition that shall be registered in JSON format and of course, CAS must be configured to accept the particular service type defined in the body. The accepted media type for this request is application/json.
So you can remove it, if you don't need the functionality.
If you do need it, you will need to define attribute names/values that can enforce authorization as the error message is telling you.
No attribute name is defined to enforce authorization when adding services via CAS REST APIs. This is likely due to misconfiguration in CAS settings where the attribute name definition is absent.
So, define:
# cas.rest.attributeName=
# cas.rest.attributeValue=
PS Don't add things you do not need.

Meaning of name attribute in JBoss MBean xml descriptor

JBoss 4/5 MBeans such as NamingAlias are defined in XML as follows
<mbean code="org.jboss.naming.NamingAlias" name=":service=NamingAlias,fromName=queue/original">
<attribute name="ToName">queue/linked</attribute>
<attribute name="FromName">queue/original</attribute>
</mbean>
Paying attention to the attributename=":service=NamingAlias,fromName=queue/original I see the parameters service and fromName.
Following the instructions to create a custom MBean here:
https://developer.jboss.org/wiki/ExampleHelloWorldService
The XML configuration for the MBean created is
<server>
<mbean code="com.acme.HelloWorldService" name="acme.com:service=HelloWorld">
<attribute name="Message">Hello World</attribute>
</mbean>
</server>
I noticed only service is specified in the name attribute.
Is service mandatory for all the beans? What about adding additional parameters such as fromName? Can these values be used from within the class that implements the MBean or are those mandated?
The name attribute can be any valid (and unique) JMX ObjectName. The keys and values themselves do not have any special significance other than their subjective significance to the developer.
In the first example, the ObjectName does not specify a domain (the value to the left of the colon) so the MBeanServer assumes the default domain, which in this case would be jboss so notionally:
:service=NamingAlias,fromName=queue/original == jboss:service=NamingAlias,fromName=queue/original
The ObjectName (and it's embedded domain and key/values) can be used within the class. In standard JMX, one would typically make the impl implement MBeanRegistration which injects the MBeanServer and ObjectName when the bean is registered. However, the example you referenced is a specialized JBoss ServiceMBean which does this automatically and your implementation will store the ObjectName in the field called serviceName.

How can I implement Picketlink Authenticator in the war layer

As the title say, I created a class in the war layer that is annotated with #Picketlink. Note that I have an ear deployment structure (ejb, war).
The custom authenticator:
#PicketLink
public class PicketlinkAuthenticator extends BaseAuthenticator { }
If I put that class in the ejb layer, the authentication is ok but when I put it to the war layer it seems like it's not found by the project as it's throwing:
20:49:46,027 INFO [org.picketlink.common] (default task-10) Using logger implementation: org.picketlink.common.DefaultPicketLinkLogger
20:49:46,043 INFO [org.picketlink.idm] (default task-10) PLIDM001000: Bootstrapping PicketLink Identity Manager
20:49:46,068 WARN [org.picketlink.idm] (default task-10) PLIDM001101: Working directory [\tmp\pl-idm] is marked to be always created. All your existing data will be lost.
20:49:46,111 INFO [org.picketlink.idm] (default task-10) PLIDM001100: Using working directory [\tmp\pl-idm].
20:49:46,127 DEBUG [org.picketlink.idm] (default task-10) No partitions to load from \tmp\pl-idm\pl-idm-partitions.db
20:49:46,152 DEBUG [org.picketlink.idm] (default task-10) Initializing Partition [6a373282-0173-4b7d-bd6a-ff0e5dc43436] with id [6a373282-0173-4b7d-bd6a-ff0e5dc43436].
20:49:46,153 DEBUG [org.picketlink.idm] (default task-10) Loaded Agents for Partition [6a373282-0173-4b7d-bd6a-ff0e5dc43436].
20:49:46,154 DEBUG [org.picketlink.idm] (default task-10) Loaded Credentials for Partition [6a373282-0173-4b7d-bd6a-ff0e5dc43436].
Why not just move the authenticator to the ejb side?
->Because I'm throwing custom error like user expired, etc. I need jsf to post these error messages.
Why not move the picketlink dependency in the web layer?
->Because my account that extended the picketlink account is binded to my services.
As suggested here I already added the picketlink module in the war project:
https://docs.jboss.org/author/display/PLINK/JBoss+Modules
<jboss-deployment-structure>
<ear-subdeployments-isolated>false</ear-subdeployments-isolated>
<sub-deployment name="THE-WAR-MODULE-THAT-REQUIRES-PICKETLINK.war">
<dependencies>
<module name="org.picketlink" />
</dependencies>
</sub-deployment>
</jboss-deployment-structure>
Anyway around this? I just want to show some custom errors :-(
I was not able to solve this problem but I have a work-around solution and that is to move the picketlink module to the web layer and just pass the identity instance to the services that need it.
I have been missing around with the same problem as well for a while now (it's 2016 now ...). What seems to make it work is to add the following CDI annotations:
#PicketLink
#Name
#RequestScoped
public class PicketlinkAuthenticator extends BaseAuthenticator { }
I would have expected the core Authentication Manager to pick this up just based on the #PicketLink Annotation, but without the CDI Annotations, the custom Authenticator class is never even loaded. Maybe there is an other way that will require us to bootstrap PicketLink - but I could not find any references.