简体   繁体   中英

How to enable authentication/authorization in Java EE7 Rest application? Getting “Client not authorized for this invocation”

I've been banging my heads against the wall for quite some time now, trying to enable authentication/authorization on a Java EE7 REST application using annotations. No matter how hard I try, I keep getting this error:

[2014-06-06T10:25:35.051+0200] [glassfish 4.0] [WARNING] [] [javax.enterprise.system.container.ejb.com.sun.ejb.containers] [tid: _ThreadID=25 _ThreadName=http-listener-2(2)] [timeMillis: 1402043135051] [levelValue: 900] [[

javax.ejb.AccessLocalException: Client not authorized for this invocation
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1895)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy453.findAll(Unknown Source)
at se.tonttu.triagebackend.service.__EJB31_Generated__CategoryFacadeREST__Intf____Bean__.findAll(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:745)
]]

After some googling I discovered people suggested deleting the glassfish/domains/domain1/generated/policy folder, but this had no effect. I also set the logging level to FINE, which gives this related log entry:

[2014-06-06T10:25:35.041+0200] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=25 _ThreadName=http-listener-2(2)] [timeMillis: 1402043135041] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.provider.BasePolicyWrapper] [METHODNAME: doImplies] [[
JACC Policy Provider, failed Permission Check at :
java.lang.Exception
at com.sun.enterprise.security.provider.BasePolicyWrapper.doImplies(BasePolicyWrapper.java:408)
at com.sun.enterprise.security.provider.BasePolicyWrapper.implies(BasePolicyWrapper.java:250)
at org.glassfish.ejb.security.application.EJBSecurityManager.authorize(EJBSecurityManager.java:761)
at com.sun.ejb.containers.BaseContainer.authorize(BaseContainer.java:2324)
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1894)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy453.findAll(Unknown Source)
at se.tonttu.triagebackend.service.__EJB31_Generated__CategoryFacadeREST__Intf____Bean__.findAll(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:125)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:91)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:346)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:341)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:101)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:224)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:198)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:946)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:323)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544)
at java.lang.Thread.run(Thread.java:745)
]]

[2014-06-06T10:25:35.044+0200] [glassfish 4.0] [INFO] [] [javax.enterprise.system.core.security] [tid: _ThreadID=25 _ThreadName=http-listener-2(2)] [timeMillis: 1402043135044] [levelValue: 800] [[
JACC Policy Provider: Failed Permission Check, context(triagebackend/triagebackend_internal)- permission(("javax.security.jacc.EJBMethodPermission" "CategoryFacadeREST" "findAll,Local,"))]]

as well as this:

[2014-06-06T10:25:35.048+0200] [glassfish 4.0] [FINE] [] [javax.enterprise.system.core.security] [tid: _ThreadID=25 _ThreadName=http-listener-2(2)] [timeMillis: 1402043135048] [levelValue: 500] [CLASSNAME: com.sun.enterprise.security.provider.BasePolicyWrapper$2] [METHODNAME: run] [[
Domain that failed(ProtectionDomain  (file:/triagebackend/triagebackend_internal <no signer certificates>)
null
<no principals>
java.security.Permissions@1dacedc (
("java.security.SecurityPermission" "getProperty.package.definition")
("java.util.PropertyPermission" "java.specification.version" "read")
("java.util.PropertyPermission" "java.version" "read")
("java.util.PropertyPermission" "os.arch" "read")
("java.util.PropertyPermission" "java.specification.vendor" "read")
("java.util.PropertyPermission" "java.vm.specification.name" "read")
("java.util.PropertyPermission" "*" "read,write")
("java.util.PropertyPermission" "java.vm.vendor" "read")
("java.util.PropertyPermission" "path.separator" "read")
("java.util.PropertyPermission" "os.version" "read")
("java.util.PropertyPermission" "file.separator" "read")
("java.util.PropertyPermission" "line.separator" "read")
("java.util.PropertyPermission" "java.vm.specification.vendor" "read")
("java.util.PropertyPermission" "java.specification.name" "read")
("java.util.PropertyPermission" "java.vendor.url" "read")
("java.util.PropertyPermission" "java.vendor" "read")
("java.util.PropertyPermission" "java.vm.version" "read")
("java.util.PropertyPermission" "java.vm.name" "read")
("java.util.PropertyPermission" "java.vm.specification.version" "read")
("java.util.PropertyPermission" "os.name" "read")
("java.util.PropertyPermission" "java.class.version" "read")
("java.net.SocketPermission" "localhost:0" "listen,resolve")
("java.net.SocketPermission" "*" "connect,resolve")
(unresolved javax.security.jacc.EJBMethodPermission MaincategoryFacadeREST count,Local,)
(unresolved javax.security.jacc.EJBMethodPermission Ksh97FacadeREST remove,Local,java.lang.Object)
(unresolved javax.security.jacc.EJBMethodPermission SolutionFacadeREST remove,Local,java.lang.Object)
*****[I've removed a lot of similar log entries here]*****
(unresolved com.sun.enterprise.security.CORBAObjectPermission * *)
(unresolved com.sun.corba.ee.impl.presentation.rmi.DynamicAccessPermission access null)
("java.io.SerializablePermission" "enableSubstitution")
("java.lang.RuntimePermission" "modifyThreadGroup")
("java.lang.RuntimePermission" "getProtectionDomain")
("java.lang.RuntimePermission" "queuePrintJob")
("java.lang.RuntimePermission" "loadLibrary.*")
("java.lang.RuntimePermission" "accessDeclaredMembers")
("java.lang.RuntimePermission" "getClassLoader")
("java.lang.RuntimePermission" "closeClassLoader")
("java.lang.RuntimePermission" "stopThread")
("java.lang.RuntimePermission" "setContextClassLoader")
("javax.management.MBeanTrustPermission" "register")
("javax.management.MBeanPermission" "[com.sun.messaging.jms.*:*]" "*")
("java.io.FilePermission" "/tmp/-" "delete")
("java.io.FilePermission" "/home/kalle/glassfish-4.0/glassfish/domains/domain1/lib/databases/-" "delete")
("java.io.FilePermission" "<<ALL FILES>>" "read,write")
("javax.security.auth.PrivateCredentialPermission" "javax.resource.spi.security.PasswordCredential * "*"" "read")
)

I've only tried implementing this at one entry point so far, and this is what the code looks like there. First I declare the role "users" (same as the group name on the glassfish server), which is then used by RolesAllowed further down. All other API calls are left unmodified, and also keep working fine.

@Stateless
@DeclareRoles({"users"})
@Path(Category.PATH)
public class CategoryFacadeREST extends AbstractFacade<Category> {
@PersistenceContext(unitName = "se.tonttu_triagebackend_war_1.0PU")
private EntityManager em;

public CategoryFacadeREST() {
    super(Category.class);
}

@GET
@RolesAllowed("users")
@Override
@Produces({"application/json"})
public Response findAll() {
    return super.findAll();
}

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

In Glassfish I've added two users in the "file" realm on the server, and this is also the default realm.

I've tried running it over both HTTP and HTTPS together with Basic Authentication (using Postman extension in Chrome), but it makes no difference.

I even tried removing the annotations and enabling authorization through web.xml,following this guide https://blogs.oracle.com/bobby/entry/simplified_security_role_mapping , but that didn't do anything at all.

I assume I've missed something really basic, but I really can't figure out what. Any help would be much appreciated, as further googling has provided nothing.

In the end, I gave up on using annotation security, and switched to using web.xml. The reason the web.xml wasn't working was because I'd forgotten to include the resource section of the URL, ie I was erroneously trying to secure /category instead of /api/category (by default Netbeans sets it to /resources , but I've changed it to /api ) as it should've been.

If anyone manages to figure out the annotation way of doing this, then by all means, do enlighten us, as I'm sure others apart from me have encountered similar problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM