Java 安全REST端点内部服务器中的多角色错误

Java 安全REST端点内部服务器中的多角色错误,java,rest,jakarta-ee,glassfish,jax-rs,Java,Rest,Jakarta Ee,Glassfish,Jax Rs,我有一个RESTful Web服务,我希望在不同的端点上允许不同的角色。例如,我有以下两个类,一个是admin角色访问的方法,另一个是manager角色访问的方法。我使用Glassfish并设置了JDBCRealm,我创建了两个用户,每个角色一个 @Stateless @Path("testrole") @DenyAll public class TestRoleREST { @RolesAllowed("admin") @GET @Path("admin") @Pro

我有一个RESTful Web服务,我希望在不同的端点上允许不同的角色。例如,我有以下两个类,一个是admin角色访问的方法,另一个是manager角色访问的方法。我使用Glassfish并设置了JDBCRealm,我创建了两个用户,每个角色一个

@Stateless
@Path("testrole")
@DenyAll
public class TestRoleREST {

   @RolesAllowed("admin")
   @GET
   @Path("admin")
   @Produces("application/xml")
   public TestData getAdmin() {
      return new TestData("admin", 0);
   }

   @RolesAllowed("manager")
   @GET
   @Path("manager/{id}")
   @Produces("application/xml")
   public TestData getManager(@PathParam("id") Integer id){
      return new TestData("manager", id);
   }


   @XmlRootElement
   @XmlAccessorType(XmlAccessType.FIELD)
   public static class TestData{
      private String roleName;
      private int number;

      private TestData(){
      }

      public TestData(String roleName, int number){
         this.roleName = roleName;
         this.number = number;
      }
   }
}
在URI:testrole/manager/2上使用curl会像预期的那样返回一些XML,对于admin用户,在URI:testrole/admin上也是如此。如果我不提供凭据,我会得到一个未授权的HTTP 401,这是预期的

curl -X GET -H "Accept:application/xml" -H "Content-Type:application/xml" -u manager:test http://localhost/server/rest/testrole/manager/2

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testData>
   <roleName>manager</roleName>
   <number>2</number>
</testData>
为什么经过身份验证的用户不接收HTTP 401、403或其他一些正常错误代码?是否有方法将应用程序配置为返回首选HTTP错误代码,或者我是否错过了一些配置

仅仅因为经过身份验证的用户试图访问未经授权的URI,就抛出从RuntimeException继承的AccessLocalException似乎有点过于苛刻


这个问题似乎涉及同样的例外和原因,但我不明白它是如何或是否与我的问题有关。当使用经过适当认证和授权的用户时,我的服务可以正常工作。

我在回答另一个不相关的问题时,找到了问题的部分解决方案。答案是使用javax.ws.rs.ext.ExceptionMapper在客户端屏蔽内部服务器异常。这仍然会导致在服务器上生成堆栈跟踪,但至少客户端不会暴露于HTTP 500代码

映射器的代码非常简单,它允许我在处理AccessLocalException时自定义响应

@Provider
public class ApplicationExceptionMapper implements ExceptionMapper<AccessLocalException> {

   @Override
   public Response toResponse(AccessLocalException exception) {
      return Response.status(Response.Status.NOT_FOUND).build();
   }
}
正如我在开始时所说的,这是一个部分答案,因为我仍然认为服务器不应该为访问未授权端点的经过身份验证的用户生成异常,但这可能是最初的开发人员的意图。如果在配置REST端点上的角色以避免生成AccessLocalException方面还有另一个难题,请共享。同时,我可以接受这个例外的解决方案

@Provider
public class ApplicationExceptionMapper implements ExceptionMapper<AccessLocalException> {

   @Override
   public Response toResponse(AccessLocalException exception) {
      return Response.status(Response.Status.NOT_FOUND).build();
   }
}