jax-rs服务RolesAllowed Annotation抛出异常

时间:2013-11-08 15:57:41

标签: java-ee jax-rs java-ee-7

我有以下jax-rs Restful API,如果我不添加以下注释行

,它可以正常工作

@RolesAllowed( “AdminRole”)

以上GET注释

package service;

import entities.Booking;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.DeclareRoles;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;


@PermitAll
@Stateless
@Path("entities.booking")
public class BookingFacadeREST extends AbstractFacade<Booking> {
    @PersistenceContext(unitName = "ofserverDBPU")

    private EntityManager em;

    public BookingFacadeREST() {
        super(Booking.class);
    }

    @POST
    @Override
    @Consumes({"application/xml", "application/json"})
    public void create(Booking entity) {
        super.create(entity);
    }

    @PUT
    @Override
    @Consumes({"application/xml", "application/json"})
    public void edit(Booking entity) {
        super.edit(entity);
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") Integer id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public Booking find(@PathParam("id") Integer id) {
        return super.find(id);
    }

    @RolesAllowed("AdminRole")
    @GET
    @Override
    @Produces({"application/xml", "application/json"})        
    public List<Booking> findAll() {
        return super.findAll();
    }

    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<Booking> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

}

通过放置上面的注释会产生以下错误。

HTTP Status 500 - Internal Server Error

type Exception report

messageInternal Server Error

descriptionThe server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: javax.ejb.EJBAccessException
root cause

javax.ejb.EJBAccessException
root cause

javax.ejb.AccessLocalException: Client not authorized for this invocation
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 4.0 logs.

GlassFish Server Open Source Edition 4.0

我在哪里做错了?

1 个答案:

答案 0 :(得分:0)

虽然有点旧,但我仍然有同样的问题(请注意,我也有一个自定义SecurityContext。经过一段时间的游荡,我终于通过编写我自己的&#34; { {1}}注释。

以下是我的进展:

首先,创建一个新的注释:

@RolesAllowed

然后,使用在身份验证阶段运行的@NameBinding @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface Secured { String role() default "all"; } 并检查权限:

ContainerRequestFilter

必须通过@Provider @Priority(Priorities.AUTHENTICATION) public class SecurityFilter implements ContainerRequestFilter { @Context private ResourceInfo resourceInfo; @Override public void filter(ContainerRequestContext crc) throws IOException { // get annotation (only for secured method) Secured security = resourceInfo.getResourceMethod().getAnnotation(Secured.class); if(security == null){ // no security on method: check the class security = resourceInfo.getResourceClass().getAnnotation(Secured.class); if(security == null) return; } // check the security, for example through the header: // crc.getHeaderString("token") // You can also inject a PersistenceContext and query your db // if the security check fails, use crc.abort() method // else, set the security context crc.setSecurityContext(new AppSecurityContext(userId, security.role())); } } web.xml构造函数中的register方法注册此过滤器。

对于Application,请查看this tutorial 。您可以稍后在服务中访问它:

AppSecurityContext

最后,使用@Context SecurityContext sctx; 注释您的班级或您的方法(或两者)。