我有以下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
我在哪里做错了?
答案 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;
注释您的班级或您的方法(或两者)。