cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with custom RestAuthenticator Using Rest 5.13

ganeshr
Champ in-the-making
Champ in-the-making
Hi,
 
   I'm developing a custom rest application with custom rest services on top of activiti-rest 5.13. As we have integrated siteminder(SSO) in application, all the request will go through the siteminder authentication using cookie value being passed from client to rest application, So I have removed extra authentication for activiti-rest services by customizing the ActivitiRestServicesApplication and created custom restAuthenticator by overriding methods requestRequiresAuthentication and isRequestAuthorized.  Returning always false in the overriding method requestRequiresAuthentication of restAuthenticator class by this I'm removing extra authentication. With this configuration able to remove authentication in verify method, but the problem is for each resource invocation again the authenticate method is invoked in SecuredResource class and trying to retrieve the loogedInUser  name.
Here is the piece of code getting invoked in ActivitiRestApplication,

public String authenticate(Request request, Response response) {
    if (!(request.getClientInfo().isAuthenticated())) {
      this.authenticator.challenge(response, false);
      return null;
    }
    return request.getClientInfo().getUser().getIdentifier();
  }

So the issue I'm facing is  request.getClientInfo().getUser() is returning as null always, because of this rest service is not called.  I'm not sure why the request.getClientInfo().getUser() is returning null. For the new custom rest service I have used SecurityContext in resource class and able to retrieve the User Principal information.  Could any one help me how to achieve the same for the existing rest services?


12 REPLIES 12

frederikherema1
Star Contributor
Star Contributor
If you have requestRequiresAuthentication to false, no authorization will be attempted, so it makes sense client-info is empty. You should fill in the clientInfo for this request yourself, prior to passing it on to the resource. Instead of setting requestRequiresAuthentication to false, you should override the authenticate method to always return true and populate the client-info with a user, based on your SSO context.

Yes, I tried that approach also but the problem is,   request.getChallengeResponse()  and request.getClientInfo().getUser() have null values. So I'm unable to retrieve the User information who have invoked the service. Is there any way in authenticate method to retrieve the user information from context. I have tried with getContext() in authenticate method to retrieve User information, but I dont see any useful methods in context object to find user information.

frederikherema1
Star Contributor
Star Contributor
If you use HTTP BASIC, the user should be filled in by the container/restlet. If you're using your own SSO, YOU should populate the user field yourself, using some kind of filter…

Thank you. I was trying to find out how we can use filter and set the restlet request data.

b_schnarr
Champ in-the-making
Champ in-the-making
Would it be enough to set the challenge credentials manually in the requestRequiresAuthentication method?

b_schnarr
Champ in-the-making
Champ in-the-making
I manually set the client info in the requestRequiresAuthenticationMethod of my custom rest authenticator this way:

<code>
org.restlet.security.User RestletUser = new org.restlet.security.User();
RestletUser.setIdentifier(userName);
ClientInfo info = new ClientInfo();
info.setUser(RestletUser);
request.setClientInfo(info);
</code>

But now, I get the following error mesages:

<code>
Internal Server Error (500) - The server encountered an unexpected condition which prevented it from fulfilling the request
at org.restlet.resource.ServerResource.doHandle(ServerResource.java:517)
at org.restlet.resource.ServerResource.get(ServerResource.java:707)
at org.restlet.resource.ServerResource.doHandle(ServerResource.java:589)
at org.restlet.resource.ServerResource.doNegotiatedHandle(ServerResource.java:649)
at org.restlet.resource.ServerResource.doConditionalHandle(ServerResource.java:348)
at org.restlet.resource.ServerResource.handle(ServerResource.java:952)
at org.restlet.resource.Finder.handle(Finder.java:246)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:155)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:84)
at org.restlet.Application.handle(Application.java:381)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.routing.Router.doHandle(Router.java:431)
at org.restlet.routing.Router.handle(Router.java:648)
at org.restlet.routing.Filter.doHandle(Filter.java:159)
at org.restlet.routing.Filter.handle(Filter.java:206)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:211)
at org.restlet.Component.handle(Component.java:392)
at org.restlet.Server.handle(Server.java:516)
at org.restlet.engine.ServerHelper.handle(ServerHelper.java:72)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:152)
at org.restlet.ext.servlet.ServerServlet.service(ServerServlet.java:1089)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database.  Cause: java.lang.NullPointerException
### Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:23)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:107)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:98)
at org.activiti.engine.impl.db.DbSqlSession.selectListWithRawParameter(DbSqlSession.java:331)
at org.activiti.engine.impl.db.DbSqlSession.selectList(DbSqlSession.java:322)
at org.activiti.engine.impl.db.DbSqlSession.selectList(DbSqlSession.java:312)
at org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityManager.findProcessDefinitionsByQueryCriteria(ProcessDefinitionEntityManager.java:57)
at org.activiti.engine.impl.ProcessDefinitionQueryImpl.executeList(ProcessDefinitionQueryImpl.java:288)
at org.activiti.engine.impl.AbstractQuery.execute(AbstractQuery.java:143)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.AbstractQuery.listPage(AbstractQuery.java:124)
at org.activiti.rest.common.api.AbstractPaginateList.paginateList(AbstractPaginateList.java:104)
at org.activiti.rest.common.api.AbstractPaginateList.paginateList(AbstractPaginateList.java:129)
at org.activiti.rest.service.api.repository.ProcessDefinitionCollectionResource.getProcessDefinitions(ProcessDefinitionCollectionResource.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.restlet.resource.ServerResource.doHandle(ServerResource.java:506)
… 62 more
Caused by: java.lang.NullPointerException
at javax.naming.ldap.Rdn.escapeStringValue(Unknown Source)
at javax.naming.ldap.Rdn.escapeValue(Unknown Source)
at org.activiti.ldap.LDAPQueryBuilder.buildQueryGroupsForUser(LDAPQueryBuilder.java:77)
at org.activiti.ldap.LDAPGroupManager$1.executeInContext(LDAPGroupManager.java:120)
at org.activiti.ldap.LDAPGroupManager$1.executeInContext(LDAPGroupManager.java:116)
at org.activiti.ldap.LDAPTemplate.execute(LDAPTemplate.java:44)
at org.activiti.ldap.LDAPGroupManager.findGroupsByUser(LDAPGroupManager.java:116)
at org.activiti.engine.impl.ProcessDefinitionQueryImpl.getAuthorizationGroups(ProcessDefinitionQueryImpl.java:234)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.ibatis.reflection.invoker.MethodInvoker.invoke(MethodInvoker.java:37)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:151)
at org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:45)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:113)
at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextMap.get(DynamicContext.java:94)
at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:113)
at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:1657)
at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:92)
at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:210)
at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:49)
at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:210)
at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:56)
at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:170)
at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:210)
at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:333)
at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:413)
at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:395)
at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:45)
at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:29)
at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:30)
at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:29)
at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:31)
at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:29)
at org.apache.ibatis.scripting.xmltags.TrimSqlNode.apply(TrimSqlNode.java:51)
at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:29)
at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:37)
at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:275)
at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:79)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:104)
… 86 more
</code>

And I have no idea, why. My identifier is the LDAP CN-Name, e.g. Mike Mayers.

Any help is highly appreciated. Therefore it would be great if someone could give a a hint.

Thank you very much
Ben

jbarrez
Star Contributor
Star Contributor
No idea really :s

You would have to see what goes in in the following line

at org.activiti.ldap.LDAPQueryBuilder.buildQueryGroupsForUser(LDAPQueryBuilder.java:77)

blackbetldev
Champ in-the-making
Champ in-the-making
This does work just to be clear Smiley Happy

<java>
        setRestAuthenticator(new RestAuthenticator() {
            @Override
            public boolean requestRequiresAuthentication(Request request) {
                final org.restlet.security.User restletUser = new org.restlet.security.User();
                restletUser.setIdentifier("XXX");
                final ClientInfo info = new ClientInfo();
                info.setUser(restletUser);
                request.setClientInfo(info);
                return false;
            }

            @Override
            public boolean isRequestAuthorized(Request request) {
                return true;
            }
        });
</java>

blackbetldev
Champ in-the-making
Champ in-the-making
IMO the guide should be updated with some of this information. I was attempting to turn off authentication completely and ran into the same issue described about (NPE on user) even though it say authentication isn't required.

For Example this doesn't work:

<java>

    public MyActivitiRestServicesApplication() {
        super();
        setRestAuthenticator(new RestAuthenticator() {
            @Override
            public boolean requestRequiresAuthentication(Request request) {
                return false;
            }

            @Override
            public boolean isRequestAuthorized(Request request) {
                return true;
            }
        });
    }
</java>

"It's possible to remove authentication from certain resources or adding additional authorisation on top of being an authenticated user (eg. being part of group X allows a user to execute request with URL Y). This can be achieved by using an implementation of org.activiti.rest.common.filter.RestAuthenticator which has 2 methods:

boolean requestRequiresAuthentication(Request request): Called before a request is checked for authentication (valid username and password is passed in header). If this method returns true, the method needs authentication. If false is returned, the request will be done regardless of the request being authenticated. If false is returned, isRequestAuthorized will not be called either for this request."


makes no mention of the need to set a user context. A simple example would be nice too Smiley Happy Thanks!