cancel
Showing results for 
Search instead for 
Did you mean: 

DeclarativeWebScript not working

kasperba
Champ in-the-making
Champ in-the-making
I have written a REST-signin call based on the Alfresco 2.1dev REST-login but when I call it from a browser then I get an exception which says the following:

freemarker.core.InvalidReferenceException: Expression ticket is undefined on line 2, column 11 in com/wannakey/user_signin.get.xml.ftl.

After some hardwork I found out that the setAuthenticationService in the Signin-class is called when Alfresco starts, but the executeImpl is never triggered. Not even when I GET the REST-call.

Alfresco's REST-login works, mine doesn't. What did I miss?


I use the following url:

http://localhost:8080/alfresco/service/user/signin?email=admin&password=admin

Below are the files that are used and they are in an AMP.

signin.java
package com.wannakey.user;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;

import org.alfresco.web.scripts.DeclarativeWebScript;
import org.alfresco.web.scripts.WebScriptRequest;
import org.alfresco.web.scripts.WebScriptStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.web.scripts.WebScriptException;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

public class SignIn extends DeclarativeWebScript {

   //    Logger
    private static final Log log = LogFactory.getLog(SignIn.class);

    // dependencies
    private AuthenticationService authenticationService;
   
    /**
     * @param authenticationService
     */
    public void setAuthenticationService(AuthenticationService authenticationService)
    {
       this.authenticationService = authenticationService;
    }
   
   @Override
   protected Map<String, Object> executeImpl(WebScriptRequest req, WebScriptStatus status) {
      
       if (authenticationService == null) {
         log.debug("Signin.executeImpl authenticationService is null");
      } else {
         log.debug("Signin.executeImpl authenticationService is NOT null");
      }
      
      log.debug("Signin.executeImpl called CurrentUser=" + authenticationService.getCurrentUserName());
      
      String email = req.getParameter("email");
      String password = req.getParameter("password");
      
      if ((email == null) || (email.length() == 0)) {
            throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "email not specified");
      }
      
      if ((password == null) || (password.length() == 0)) {
            throw new WebScriptException(HttpServletResponse.SC_BAD_REQUEST, "Password not specified");
      }
      
      try
        {
            // get ticket
            authenticationService.authenticate(email, password.toCharArray());

            // add ticket to model for javascript and template access
            Map<String, Object> model = new HashMap<String, Object>(7, 1.0f);
            model.put("ticket",  authenticationService.getCurrentTicket());
            return model;
        }
        catch(AuthenticationException e)
        {
            throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "Signin failed");
        }
        finally
        {
            authenticationService.clearCurrentSecurityContext();
        }
   }
}

signin.get.desc.xml
<webscript>
  <shortname>signin</shortname>
  <description>Sign in with your wannakey-account</description>
  <url>/user/signin?email={email}&amp;password={password}</url>
  <format default="xml"/>
  <authentication>none</authentication>
  <transaction>required</transaction>
</webscript>

signin.get.xml.ftl
<?xml version="1.0" encoding="UTF-8"?>
<ticket>${ticket}</ticket>

module-context.xml
<bean id="webscript.com.wannakey.signin.get"
             class="com.wannakey.user.SignIn" parent="webscript"
             abstract="false" singleton="true" lazy-init="default"
             autowire="default" dependency-check="default">
      <property name="authenticationService" ref="authenticationService" />
   </bean>
19 REPLIES 19

davidc
Star Contributor
Star Contributor
I suspect your Spring bean has not been hooked into your Web Script.

If you switch on:

log4j.logger.org.alfresco.web.scripts=debug

in

log4j.properties

and re-start the server (or 'refresh web scripts' from /alfresco/service/), all registered web scripts are logged including their Spring bean

e.g.

Found Web Script org/alfresco/repository/loginticket.delete (desc: org/alfresco/repository/loginticket.delete.desc.xml, impl: webscript.org.alfresco.repository.loginticket.delete, auth: user, trx: required, format style: any, default format: xml)

If you have:

impl: webscript_default

then your bean is not hooked up.  You need to adjust the id of the Spring bean.

kasperba
Champ in-the-making
Champ in-the-making
You are right about IMPL = webscript_default.

12:09:52,875 DEBUG [org.alfresco.web.scripts.DeclarativeWebScriptRegistry] Found Web Script com/wannakey/user/signin.get (desc: com/wannakey/user/signin.get.desc.xml, impl: webscript_default, auth: none, trx: required, format style: any, default format: html)

"adjust the id of the Spring bean"? you just lost me there  Smiley Surprisedops:

If you could describe what I should do because I can't remember that I have given this spring bean an id and I wouldn't know how.

davidc
Star Contributor
Star Contributor
Ok.

<bean id="webscript.com.wannakey.signin.get"
class="com.wannakey.user.SignIn" parent="webscript"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="authenticationService" ref="authenticationService" />
</bean>

The id of a Web Script bean must comply with the following naming convention:

webscript.<packageId>.<serviceId>.<httpMethod>

So, I know your serviceId (signin) and httpMethod (get) are correct, so it must be the packageId that's wrong.

Where have you placed your script (in which folder)?  The folder is your package.  Replace / with .

e.g. Alfresco's login script is in the folder

org/alfresco/repository

therefore its packageId is

org.alfresco.repository

and its web script bean id is

webscript.org.alfresco.repository.login.get

kasperba
Champ in-the-making
Champ in-the-making
Yes, that was the problem.

Thanks for you help.

tsgpartner_mui
Champ in-the-making
Champ in-the-making
where did you put your context.xml?


I placed mine in Alfresco\tomcat\shared\classes\alfresco\extension,

but returns an error:


12:45:37,533 ERROR [[Catalina].[localhost].[/alfresco]] Exception sending context initialized event to listener instance of class org.alfresco.web.app.ContextListener
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.tsgrp.alfresco.webscript.SignInWebScript] for bean with name 'webscript.com.tsgrp.signin.get' defined in file [C:\Alfresco\tomcat\shared\classes\alfresco\extension\auth-context.xml]; nested exception is java.lang.ClassNotFoundException: com.tsgrp.alfresco.webscript.SignInWebScript
Caused by:
java.lang.ClassNotFoundException: com.tsgrp.alfresco.webscript.SignInWebScript
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1359)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1205)
        at org.springframework.util.ClassUtils.forName(ClassUtils.java:183)
        at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:317)
        at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1044)
        at org.springframework.beans.factory.support.AbstractBeanFactory.isBeanClassMatch(AbstractBeanFactory.java:1072)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:165)
        at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:691)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:395)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:328)



Im pretty sure the bean ID naming convention is correct, maybe its the class??

tsgpartner_mui
Champ in-the-making
Champ in-the-making
Having trouble gettin my bean to bind with my web script…


If anyone can help



I put my custom context.xml in C:\Alfresco\tomcat\shared\classes\alfresco\extension.


I put my desc.xml and ftl file in
C:\Alfresco\tomcat\shared\classes
then, create a directory within \templates\webscripts\<namespace>\desc.xml, etc.


Then I put my compiled JAR file of my .java file in
C:\Alfresco\tomcat\webapps\alfresco\WEB-INF\lib


I know the naming convention in my context.xml is correct.  Are these the steps I need to create a java-backed webscript, and bind the bean into the webscript????  Because, I still keep getting class not found error.



Thanks

davidc
Star Contributor
Star Contributor
Is

com.tsgrp.alfresco.webscript.SignInWebScript

in your classpath?

tsgpartner_mui
Champ in-the-making
Champ in-the-making
<bean id="webscript.com.tsgrp.signin.get" class="com.tsgrp.alfresco.webscript.SignInWebScript" parent="webscript"
      abstract="false" singleton="true" lazy-init="default"
      autowire="default" dependency-check="default">
      <property name="authenticationService" ref="authenticationService" />
</bean>


This is in my context.xml



In my java file, package com.tsgrp.alfresco.webscript

davidc
Star Contributor
Star Contributor
Is your SignInWebScript.class file in your classpath?