On Tue, Jul 29, 2025 at 05:22:38PM +0200, Jean-Baptiste Onofré wrote:
> Hi everyone,
>
> I submit the Apache Karaf 4.4.8 release to your vote.
>
> This release is a maintenance release on the 4.4.x series bringing
> fixes and updates, especially:
> - 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
>
> Maven Staging Repository:
> https://repository.apache.org/content/repositories/orgapachekaraf-1195/
>
> Dist Staging Repository:
> https://dist.apache.org/repos/dist/dev/karaf/4.4.8/
>
> Git tag:
> karaf-4.4.8
>
> Please vote to approve this release:
> [ ] +1 Approve the release
> [ ] -1 Don't approve the release (please provide specific comments)
>
> This vote will be open for at least 72 hours.
>
> Regards
> JB
Hello,
Currently I use the karaf service guard with an acl for my service. This
works for the shell, as well as my JAX-RS setup (allowing both a REST
and CLI based authc/authz with a centralized policy). While I use Shiro
on the REST side, I wrap the invocations with an interceptor to populate
what Karaf wants for doing lookups.
@Slf4j
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;
});
}
}
where SecurityUtilities.runAs:
public static <T> T runAs(final Subject subject, final PrivilegedAction<T>
action) {
if (CALL_AS_METHOD.isPresent()) {
try {
// Java 21+ path: invoke Subject.callAs(subject, action)
@SuppressWarnings("unchecked")
final T result = (T) CALL_AS_METHOD.get().invoke(null, subject, action);
return result;
} catch (final ReflectiveOperationException ex) {
// Fallback to legacy doAs on error
}
}
// Pre-Java 21 fallback or callAs failed: use legacy Subject.doAs(...)
return Subject.doAs(subject, action);
}
I also have SecurityUtilities.toJaasSubject:
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());
}
This allows me to authenticate to the REST service and still use the
service guard to check for my authorization (roles) because of populated
the JAASSubject with roles from User/Roles Karaf expects.
I do something similar when accessing the Subject from the service as
in:
public static Optional<Subject> getCurrentSubject() {
if (CURRENT_METHOD.isPresent()) {
try {
// Java 21+ path: invoke Subject.current()
final Subject subject = (Subject) CURRENT_METHOD.get().invoke(null);
return Optional.ofNullable(subject);
} catch (final ReflectiveOperationException e) {
// Fallback to empty on error
return Optional.empty();
}
} else {
// Pre-Java 21 fallback: use legacy method
final Subject subject = Subject.getSubject(AccessController.getContext());
return Optional.ofNullable(subject);
}
}
Another future proof using Subject.current().
Question:
Are the changes proposed here going to break all this for me?