Hans
Hans

Reputation: 165

How to propagate SecurityContext to EJB container in JBOSS EAP 8

I am using JBOSS EAP 8. I package in a single war file For 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 work WFLYEJB0364: Aufruf an Methode: public java.lang.String ejb.SecuredService.performAdminTask() von Bean: SecuredService ist nicht gestattet Translates 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.

Upvotes: 0

Views: 28

Answers (0)

Related Questions