Using a secured EJB from a JAX-RS web service

2019-05-18 04:11发布

I'm running Glassfish 4 and Jersey as JAX-RS implementation. I have secured my EJB like this:

@Stateless
@DeclareRoles({"Authentication_Reader"})
@RolesAllowed({"Authentication_Reader"})
public class AuthenticationServiceBean { 
   public void foo() {
      ... 
   }

}

I have created a security-role-mapping entry in glassfish-web.xml, and I've also created a security-role declaration in web.xml.

The following works from a servlet:

@WebServlet(name = "TestServlet", urlPatterns = {"/test.do"})
@RunAs("Authentication_Reader")
public class TestServlet extends HttpServlet {

    @Inject
    private AuthenticationServiceBean authenticationService;

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       authenticationService.foo();
        .. etc ...
    }
}

But if I do it from a JAX-RS resource, such as this one:

@RequestScoped
@RunAs("Authentication_Reader")
@Path("test")
public class TestResource {
    @Inject
    private AuthenticationServiceBean authenticationServiceBean;

    @GET
    public String test() {
        int x = 123;  // This code executes fine
        authenticationServiceBean.foo();   // This gets an AccessLocalException
        return "I never returned this";
    }
}

The Glassfish server log basically says: javax.ejb.AccessLocalException: Client not authorized for this invocation

I don't understand why this works for a servlet, and not for the REST resource. To me, this seems like it should work just fine.

1条回答
萌系小妹纸
2楼-- · 2019-05-18 05:01

If you change TestResource to be EJB and if you inject AuthenticationServiceBean using @EJB it should work.

You can look at jersey-ejb example. And there is also jersey-gf-ejb integration module to be used to use EJBs on Glassfish AS. This is Jersey specific, JAX-RS does not support to inject EJB into Resource class yet.

查看更多
登录 后发表回答