如何使用@Stateless工作制作泽西@RolesAllowed?

问题描述 投票:0回答:1

我不确定这是否可能,但我正在尝试设置EJB + JAX-RS(Jersey)测试项目并使用@RolesAllowed注释。

我目前收到以下错误日志:

Warning:   WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception
Severe:   ejb.stateless_ejbcreate_exception
Warning:   A system exception occurred during an invocation on EJB TestSB, method: public java.util.List rest.sb.TestSB.findAll()
Warning:   javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB

相关课程:

application config.Java

@ApplicationPath("rest")
public class ApplicationConfig extends ResourceConfig {

    public ApplicationConfig() {
        packages("rest");
        register(RolesAllowedDynamicFeature.class);
    }
}

test SB facade.Java

@Local
public interface TestSBFacade {

    public List<Test> findAll();
}

test SB.Java

@Stateless
@Path("secured/test")
public class TestSB implements TestSBFacade {

    @DAO @Inject
    private TestDAOFacade dao;

    @Context
    SecurityContext securityContext;

    @Secured
    @RolesAllowed({"READ"})
    @Path("all")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Override
    public List<Test> findAll() {
        //this works without the @RolesAllowed so it is a possible workaroud for now.

        System.out.println(securityContext.isUserInRole("READ")); //output: true
        return dao.findAll();
    }
}

AU TH filter.Java

@Provider
@Secured //NameBinding
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        String token = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        try {
            verifyToken();
            createSecurityContext();
        } catch (Exception e) {
            Logger.getLogger(AuthenticationFilter.class.getName()).log(Level.SEVERE, null, "Invalid or Expired JWT");
            requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
        }

    }
}

我的SecurityContext已设置并正常工作,@ RolesAllowed似乎是问题,因为我没有错误,如果我删除它并且JSON正确返回到前端。保持@RolesAllowed会导致开头提到的错误。

但是,我想使用方便的注释,而不是在isUserInRole IF语句中嵌入每个方法。任何帮助和见解都非常感谢。

java jax-rs jersey-2.0 ejb-3.1
1个回答
1
投票

显然,由于使用@RolesAllowed的EJB和JAX-RS实现,它们并不能很好地协同工作。所以我决定创建自己的Annotation并在ApplicationConfig.java中注册我自己的DynamicFeature。

authorized.Java

@Documented
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Authorized {
    public String[] value() default "";
}

authorization dynamic feature.Java

public class AuthorizationDynamicFeature implements DynamicFeature {

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext featureContext) {

        Authorized auth = new AnnotatedMethod(resourceInfo.getResourceMethod()).getAnnotation(Authorized.class);
        if (auth != null) {
            featureContext.register(new AuthorizationRequestFilter(auth.value()));
        }
    }

    @Priority(Priorities.AUTHORIZATION)
    private static class AuthorizationRequestFilter implements ContainerRequestFilter {

        private final String[] roles;

        AuthorizationRequestFilter() {
            this.roles = null;
        }

        AuthorizationRequestFilter(final String[] roles) {
            this.roles = roles;
        }

        @Override
        public void filter(final ContainerRequestContext requestContext) throws IOException {
            if (!this.roles[0].isEmpty()) {
                for (final String role : this.roles) {
                    if (requestContext.getSecurityContext().isUserInRole(role)) {
                        return;
                    }
                }
                throw new ForbiddenException(LocalizationMessages.USER_NOT_AUTHORIZED());
            }
        }
    }
}

非常感谢@PaulSamsotha带领我找到更合适的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.