Hello, I am using karaf 4.3.7 and yes I saw the examples in karaf. The version used is 1.0.6 which is pretty old. I tried to update to 1.0.10 but i dont see what is going wrong. There is the Application, Servlet, and Whiteboard. But the servlet is not accessible. With version 2.0.1 is cxf-core required. That would also be fine. Unfortunately it does not work without a url prefix which would require a change on the client side.
@ João thank you very much for your help. Do you also have a repo link to a working example; where does the JWTService come from? Thank br, Matthias Am Do., 23. Juni 2022 um 11:02 Uhr schrieb João Assunção < [email protected]>: > Hello Matthias, > > Regarding authentication I normally use a ContainerRequestFilter. > Follows an example of a filter where authentication is done using a JWT > token. > It uses JwtService that is responsible for creating and validating tokens. > It uses jose4j. > > > @Secured >> @Provider >> @Priority(Priorities.AUTHENTICATION) >> @Component(scope = ServiceScope.PROTOTYPE, // >> service = { ContainerRequestFilter.class }, // >> property = { >> JaxrsWhiteboardConstants.JAX_RS_EXTENSION + "=" + true, // >> JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + >> "TokenAuthenticationFilter", // >> Constants.JAX_RS_APPLICATION_SELECT, // >> }) >> public class TokenAuthenticationFilter implements ContainerRequestFilter { >> >> private static final Logger LOGGER = >> LoggerFactory.getLogger(TokenAuthenticationFilter.class); >> >> private static final String AUTHENTICATION_SCHEME = "Bearer"; >> >> private static final String AUTHENTICATION_SCHEME_PREFIX = >> AUTHENTICATION_SCHEME + " "; >> >> @Reference(cardinality = ReferenceCardinality.MANDATORY) >> JwtService jwtService; >> >> @Context >> private ResourceInfo resourceInfo; >> >> @Override >> public void filter(ContainerRequestContext requestContext) throws >> IOException { >> >> // Get the Authorization header from the request >> String authorizationHeader = >> requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); >> LOGGER.debug("authorizationHeader {}", authorizationHeader); >> // Validate the Authorization header >> if (!isTokenBasedAuthentication(authorizationHeader)) { >> LOGGER.info("Missing auth token. Aborting"); >> abortWithUnauthorized(requestContext); >> return; >> } >> // Extract the token from the Authorization header >> final String token = >> authorizationHeader.substring(AUTHENTICATION_SCHEME_PREFIX.length()); >> try { >> // Validate the token. An exception will be thrown if invalid >> SubjectDetails subjectDetails = >> jwtService.validateToken(token); >> LOGGER.debug("Token for subject {} accepted", >> subjectDetails.getId()); >> initSecurityContext(requestContext, subjectDetails); >> Permission requiredPermission = >> getPermissionForResource(resourceInfo); >> if (!subjectDetails.hasPermission(requiredPermission)) { >> LOGGER.debug("subject {} lack permission {}", >> subjectDetails.getId(), requiredPermission); >> abortWithForbidden(requestContext); >> } >> } >> catch (AuthenticationException e) { >> LOGGER.trace("Ignored", e); >> LOGGER.info("Token validation failed. Aborting"); >> abortWithUnauthorized(requestContext); >> } >> } >> >> /** >> * @param requestContext >> * @param subjectDetails >> */ >> private void initSecurityContext(ContainerRequestContext >> requestContext, SubjectDetails subjectDetails) { >> >> final SecurityContext currentSecurityContext = >> requestContext.getSecurityContext(); >> boolean secure = currentSecurityContext.isSecure(); >> requestContext.setSecurityContext(new >> InternalSecurityContext(subjectDetails, secure)); >> >> } >> >> private boolean isTokenBasedAuthentication(String >> authorizationHeader) { >> >> // Check if the Authorization header is valid >> // It must not be null and must be prefixed with "Bearer" plus a >> // whitespace >> // The authentication scheme comparison must be case-insensitive >> return StringUtils.startsWithIgnoreCase(authorizationHeader, >> AUTHENTICATION_SCHEME_PREFIX); >> } >> >> private void abortWithUnauthorized(ContainerRequestContext >> requestContext) { >> >> // Abort the filter chain with a 401 status code response >> // The WWW-Authenticate header is sent along with the response >> requestContext.abortWith( >> Response.status(Response.Status.UNAUTHORIZED) >> .header(HttpHeaders.WWW_AUTHENTICATE, >> AUTHENTICATION_SCHEME + " realm=\"" + >> Constants.APP_NAME + "\"") >> .build()); >> } >> >> private void abortWithForbidden(ContainerRequestContext >> requestContext) { >> >> >> requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build()); >> } >> >> static Permission getPermissionForResource(ResourceInfo resourceInfo) >> { >> >> Permission permission = >> extractPermission(resourceInfo.getResourceMethod()); >> if (permission != null) { >> return permission; >> } >> permission = extractPermission(resourceInfo.getResourceClass()); >> return permission; >> >> } >> >> // Extract Permission from the annotated element >> static Permission extractPermission(AnnotatedElement >> annotatedElement) { >> >> if (annotatedElement == null) { >> return null; >> } >> Secured secured = annotatedElement.getAnnotation(Secured.class); >> return secured == null ? null : secured.value(); >> } >> >> private static class InternalSecurityContext implements >> SecurityContext { >> >> private final boolean secure; >> >> private final SubjectDetails subjectDetails; >> >> InternalSecurityContext(SubjectDetails subjectDetails, boolean >> secure) { >> >> this.subjectDetails = subjectDetails; >> this.secure = secure; >> } >> >> @Override >> public Principal getUserPrincipal() { >> >> return subjectDetails; >> } >> >> @Override >> public boolean isUserInRole(String role) { >> >> // We are not using role base authorization >> return true; >> } >> >> @Override >> public boolean isSecure() { >> >> return secure; >> } >> >> @Override >> public String getAuthenticationScheme() { >> >> return AUTHENTICATION_SCHEME; >> } >> >> } >> >> /** >> * For test purposes >> * >> * @param jwtService >> * @return >> */ >> public static TokenAuthenticationFilter createTestInstance(JwtService >> jwtService) { >> >> TokenAuthenticationFilter filter = new >> TokenAuthenticationFilter(); >> filter.jwtService = jwtService; >> return filter; >> } >> } >> > > The Secured annotation is used to mark the methods that need to be > protected and the required permission. > > @NameBinding >> @Retention(RetentionPolicy.RUNTIME) >> @Target({ ElementType.TYPE, ElementType.METHOD }) >> public @interface Secured { >> >> Permission value() default Permission.AUTHENTICATED; >> } >> > > João Assunção > > Email: [email protected] > Mobile: +351 916968984 > Phone: +351 211933149 > Web: www.exploitsys.com > > > > > On Wed, Jun 22, 2022 at 8:54 PM Matthias Leinweber < > [email protected]> wrote: > >> Hello Karaf user, >> >> i try to get aries-jax-rs-whiteboard in a version > 1.0.6 running without >> success. 2.0.1 with installed cxf is working fine. But in 1.0.7-1.0.10. >> http:list does not show a servlet and my jaxrs whiteboard resources are not >> working. >> >> Any hints which component needs to be installed? Reading BNDrun + >> Components DSL is pretty confusing. >> >> Btw, does anyone have a good example for authentication? Shiro seems to >> be a bit overkill. >> >> br, >> Matthias >> >
