jax-rs服务RolesAllowed Annotation抛出异常 [英] jax-rs service RolesAllowed Annotation throwing exception

查看:222
本文介绍了jax-rs服务RolesAllowed Annotation抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下jax-rs Restful API,如果我不添加以下注释行可以正常工作

I have following jax-rs Restful API which works fine if I won't add following Annotation line

@RolesAllowed(AdminRole)

@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;
    }

}

通过置于上方注释会出现以下错误。

By placing above annotation gives following error.

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

我在哪里做错了?

推荐答案

这有点旧,但我仍有同样的问题(注意我也有自定义 SecurityContext 。在徘徊了一段时间之后,我终于通过编写自己的 @RolesAllowed 注释来实现它。

It is a bit old, but I still have the same problem (note that I also have a custom SecurityContext. After wandering around a while, I finally made it work by writing my own "@RolesAllowed annotation.

以下是我的处理方式:

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

First, create a new annotation:

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Secured {
    String role() default "all";
}

然后,使用 ContainerRequestFilter 身份验证阶段运行并检查权限:

Then, use a ContainerRequestFilter running at the authentication phase and checking the permissions:

@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()));
     }
 }

此过滤器必须通过<$ c $注册c> web.xml 或在应用程序构造函数中使用 register 方法。

This filter must be registered either through web.xml or using the register method in your Application constructor.

对于 AppSecurityContext ,请查看本教程。您可以在以后的服务中访问它:

For the AppSecurityContext, have a look at this tutorial . It can be accessed later in your service with:

@Context
SecurityContext sctx;

最后,使用注释您的班级或您的方法(或两者) @Secure(role =somerole)

这篇关于jax-rs服务RolesAllowed Annotation抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆