On Tue, Aug 19, 2025 at 05:21:54PM +0200, Jean-Baptiste Onofré wrote:
> The Apache Karaf team is pleased to announce Apache Karaf runtime 4.4.8 
> release.
> 
> Apache Karaf runtime 4.4.8 is a maintenance release, especially bringing:
> * SecurityContext returns RolePrincipal instead of UserPrincipal in JAX-RS
> * Several improvements on JAAS layer
> * New BoM (light)
> * Java26 support
> * Full build using JDK11 (including javase 11 in the resolver)
> * A bunch of dependency updates
> 
> You can take a look on the Release Notes for details:
> https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12311140&version=12354828
> 
> You can download Apache Karaf runtime 4.4.8 here:
> https://karaf.apache.org/download.html
> 
> Enjoy!
> The Apache Karaf team

Hello,

I having trouble migrating to the new JAAS security changes. I am using
the Karaf service guard in order to protect specific methods based on
which role they have. This works fine for when logging in as a user.
However, I also expose a REST service via CXF. Authentication is done
through Shiro with Aries JAX-RS integration -- I then convert this Shiro
authenticated user into a JAAS Subject using the Karaf UserPrincipal and
RolePrincpal and intercept the calls running it in a SecurityContext.
This allows the service guard to continue to work. The changes in 4.4.8
break this for me. I'm having trouble figuring out what exactly I need
to change to replicate the behavior. Any advice would be greatly
appreciated.

Example:

import org.apache.karaf.jaas.boot.principal.RolePrincipal;
import org.apache.karaf.jaas.boot.principal.UserPrincipal;

  public static Subject toJaasSubject(@NonNull final RichPrincipal 
richPrincipal) {
    final Set<Principal> principals = new HashSet<>();

    // Add the main user principal (identity) to the JAAS Subject
    principals.add(new UserPrincipal(richPrincipal.name()));

    // Add roles as RolePrincipals
    richPrincipal.roles().forEach(role -> principals.add(new 
RolePrincipal(role)));

    // Add permissions as RolePrincipals (assuming permissions are handled 
similarly)
    richPrincipal
        .permissions()
        .forEach(permission -> principals.add(new RolePrincipal(permission)));

    // Construct the JAAS Subject with principals, no public/private credentials
    return new Subject(true, principals, Set.of(), Set.of());
  }

and then there is a CXF interceptor which runs this in a
Subject.call(do)As

public class JaasSubjectDoAsInterceptor extends 
AbstractPhaseInterceptor<Message> {

  public JaasSubjectDoAsInterceptor() {
    super(Phase.PRE_INVOKE);
  }

  @Override
  public void handleMessage(final Message message) {
    final org.apache.shiro.subject.Subject shiroSubject = 
SecurityUtils.getSubject();
    if (shiroSubject == null
        || !(shiroSubject.getPrincipal() instanceof RichPrincipal 
userPrincipal)) {
      return;
    }
    SecurityUtilities.runAs(
        SecurityUtilities.toJaasSubject(userPrincipal),
        () -> {
          message.getInterceptorChain().doIntercept(message);
          return null;
        });
  }

with this I can just @Reference my service and call the appropriate
method associated with the REST endpoint and the service guard will
ensure I have the right group. I have multiple Shiro Realm's I'm
authenticating against (i.e. GitLab) and I convert the
groups/permissions into karaf RolePrincipals for use with the below
service guard ACL for example.

service.guard = (objectClass=com.example.MyService)

# Initially allow everything (needed for registration)
* = *

# Objects
getObject* = someGroup

V/r,


-- 
Chaz

Reply via email to