I am using JBOSS EAP 8. I package in a single war fileFor learning purposes I have implemented a REST API with a login Endpoint which returns a JWToken to the client. Other REST endpoints are protected by
import java.io.IOException;import java.util.Base64;import jakarta.annotation.Priority;import jakarta.ws.rs.Priorities;import jakarta.ws.rs.container.ContainerRequestContext;import jakarta.ws.rs.container.ContainerRequestFilter;import jakarta.ws.rs.core.HttpHeaders;import jakarta.ws.rs.core.Response;import jakarta.ws.rs.ext.Provider;import io.jsonwebtoken.Claims;import io.jsonwebtoken.Jwts;@Provider@Priority(Priorities.AUTHENTICATION)public class JWTAuthenticationFilter implements ContainerRequestFilter { private static final String SECRET_KEY = Base64.getEncoder().encodeToString("your-256-bit-secret-key-in-base64".getBytes()); @Override public void filter(ContainerRequestContext requestContext) throws IOException { String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); if (authHeader == null || !authHeader.startsWith("Bearer ")) { return; // No token, skip authentication } String token = authHeader.substring(7); // Strip "Bearer " try { Claims claims = parseToken(token); String username = claims.getSubject(); String role = (String) claims.get("role"); if (username != null && role != null) { // Set a custom security context with the principal and role requestContext.setSecurityContext(new JWTSecurityContext(username, role)); } else { abortWithUnauthorized(requestContext); } } catch (Exception e) { abortWithUnauthorized(requestContext); } } private Claims parseToken(String token) { return Jwts.parserBuilder() .setSigningKey(Base64.getDecoder().decode(SECRET_KEY)) .build() .parseClaimsJws(token) .getBody(); } private void abortWithUnauthorized(ContainerRequestContext requestContext) { requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).entity("Unauthorized").build()); }}public class JWTSecurityContext implements SecurityContext { private final JWTPrincipal principal; private final String role; public JWTSecurityContext(String username, String role) { this.principal = new JWTPrincipal(username); this.role = role; } @Override public Principal getUserPrincipal() { return principal; } @Override public boolean isUserInRole(String role) { return this.role != null && this.role.equals(role); } @Override public boolean isSecure() { return true; // Assume HTTPS is used } @Override public String getAuthenticationScheme() { return "Bearer"; }}
This works fine. The token is processed and Username and Role are extracted.
@Path("/api")public class AdminEndpoint { @EJB private SecuredService securedService; @GET @Path("/admin") @Produces(MediaType.TEXT_PLAIN) public Response adminEndpoint(@Context HttpHeaders headers) { return Response.ok(securedService.performAdminTask()).build(); }}But I want to use the role to authorize @Stateless@DeclareRoles({"Admin"})public class SecuredService { @RolesAllowed({"Admin"}) public String performAdminTask() { String result = "Admin task performed!"; System.out.println(result); return result; }}
This does not workWFLYEJB0364: Aufruf an Methode: public java.lang.String ejb.SecuredService.performAdminTask() von Bean: SecuredService ist nicht gestattetTranslates to caoll of method … not allowed.I have not figured out how to propagate the SecurityContext to the EJB.Any help would be greatly appreciated.