Re: [Dspace-tech] CAS Authentication for DSpace 1.4

22 views
Skip to first unread message

Tonny H. Laursen

unread,
Aug 24, 2015, 4:18:04 PM8/24/15
to dspac...@lists.sourceforge.net, NS Hashmi, Information Systems and Computing
Hi,

I have now tried to patch my installation with the command 'patch -p0
< caspatch' from the dspace source directory.
I downloaded the file 'cas-client-java-2.1.1.tar.gz' from the CAS/
Yale site. I used Ant and copied the casclient.jar to the 'lib'
directory.
I have changed the dspace.cfg file.

When im trying to login to dspace, i get the login page from our CAS
server. When i have logged in (after clicked login), it seems like
the loginpage are being redirected round and round, i can see in the
URL that i get a new ticket everytime.

In the dspace.log file i have:

2006-11-23 10:50:47,274 INFO org.dspace.eperson.CASAuthentication @
anonymous:session_id=FFFB7A25006745F0CAF11EABB371AC1A:ip_addr=xxx.xxx.xx
x.xxx:login:CAS validate: https://xxxx.xxx/validate
2006-11-23 10:50:47,325 ERROR org.dspace.eperson.CASAuthentication @
Unexpected exception caught
org.xml.sax.SAXParseException: Content is not allowed in prolog.
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown
Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse
(Unknown Source)
at edu.yale.its.tp.cas.client.ServiceTicketValidator.validate
(ServiceTicketValidator.java:221)
at org.dspace.eperson.CASAuthentication.validate
(CASAuthentication.java:291)
at org.dspace.eperson.CASAuthentication.authenticate
(CASAuthentication.java:173)
at
org.dspace.eperson.AuthenticationManager.authenticateInternal
(AuthenticationManager.java:200)
at
org.dspace.eperson.AuthenticationManager.authenticateImplicit
(AuthenticationManager.java:178)
at org.dspace.app.webui.util.Authenticate.startAuthentication
(Authenticate.java:188)
at org.dspace.app.webui.filter.RegisteredOnlyFilter.doFilter
(RegisteredOnlyFilter.java:94)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke
(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke
(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service
(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process
(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol
$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket
(PoolTcpEndpoint.java:527)
at
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt
(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool
$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
2006-11-23 10:50:47,325 ERROR org.dspace.eperson.CASAuthentication @
Unexpected exception caught
javax.servlet.ServletException: Content is not allowed in prolog.
at org.dspace.eperson.CASAuthentication.validate
(CASAuthentication.java:294)
at org.dspace.eperson.CASAuthentication.authenticate
(CASAuthentication.java:173)
at
org.dspace.eperson.AuthenticationManager.authenticateInternal
(AuthenticationManager.java:200)
at
org.dspace.eperson.AuthenticationManager.authenticateImplicit
(AuthenticationManager.java:178)
at org.dspace.app.webui.util.Authenticate.startAuthentication
(Authenticate.java:188)
at org.dspace.app.webui.filter.RegisteredOnlyFilter.doFilter
(RegisteredOnlyFilter.java:94)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter
(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke
(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke
(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke
(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke
(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke
(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service
(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process
(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol
$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:664)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket
(PoolTcpEndpoint.java:527)
at
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt
(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool
$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
2006-11-23 10:50:47,326 INFO org.dspace.eperson.CASAuthentication @
CAS server: https://xxxxxx.xxx/login

Anyone that have an idea why it is doing this?

Thanks,
Tonny


Den 22/11/2006 kl. 17.57 skrev NS Hashmi, Information Systems and
Computing:

> Hi Tonny,
>
> I've released the patch for CAS (Single Sign On) authentication to
> work with DSpace 1.4, see following link:
>
> <http://sourceforge.net/tracker/index.php?
> func=detail&aid=1601221&group_id=19984&atid=319984>
>
> I'd be grateful if you could test the patch, let me know if you
> have any problems or ideas on how to improve the code. You will
> have to slightly modify the patch to your requirements.
>
> Thanks,
>
> Naveed
> --------------------------------------------------------
> Naveed Hashmi
> Information Systems and Computing
> University of Bristol
>
>
>


NS Hashmi, Information Systems and Computing

unread,
Aug 24, 2015, 4:18:05 PM8/24/15
to Tonny H. Laursen, dspac...@lists.sourceforge.net
Hi Tonny,

Can you forward me a copy of your CASAuthentication.java class.

Thanks,

Naveed
Naveed...@bristol.ac.uk



Tonny H. Laursen

unread,
Aug 24, 2015, 4:18:06 PM8/24/15
to NS Hashmi, Information Systems and Computing, dspac...@lists.sourceforge.net

Here you go Naveed,

/*
* CASAuhentication.java
*
* Version: $Revision: 1.0 $
*
* Date: $Date: 2006/11/22 21:16:38 $
*
* Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
* Institute of Technology. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of the Hewlett-Packard Company nor the name of the
* Massachusetts Institute of Technology nor the names of their
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/

package org.dspace.eperson;

import org.apache.log4j.Logger;
import org.dspace.app.webui.util.JSPManager;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;

import org.dspace.eperson.Group;
import org.dspace.eperson.AuthenticationMethod;
import org.dspace.eperson.AuthenticationManager;
import org.dspace.authorize.AuthorizeException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.jstl.fmt.LocaleSupport;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.sql.SQLException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

// we use the Java CAS client
import edu.yale.its.tp.cas.client.*;

/**
* Authenticator for Central Authentication Service (CAS).
*
* @author Naveed Hashmi, University of Bristol
* based on code developed by Nordija A/S (www.nordija.com) for Center
of Knowledge Technology (www.cvt.dk)
* @version $Revision: 1.0 $
*/

public class CASAuthentication
implements AuthenticationMethod {

/** log4j category */
private static Logger log = Logger.getLogger
(CASAuthentication.class);

private static String casServicevalidate; //URL to validate ST
tickets
private static String casProxyvalidate; //URL to validate PT
tickets

// (optional) store user's details for self registration, can
get this info from LDAP, RDBMS etc
private String email;
private String firstName;
private String lastName;

/**
* Predicate, can new user automatically create EPerson.
* Checks configuration value. You'll probably want this to
* be true to take advantage of a Web certificate infrastructure
* with many more users than are already known by DSpace.
*/
public boolean canSelfRegister(Context context,
HttpServletRequest request,
String username)
throws SQLException
{
return ConfigurationManager.getBooleanProperty(
"webui.cas.autoregister");
}

/**
* Nothing extra to initialize.
*/
public void initEPerson(Context context, HttpServletRequest
request,
EPerson eperson)
throws SQLException
{
}

/**
* We don't use EPerson password so there is no reason to change
it.
*/
public boolean allowSetPassword(Context context,
HttpServletRequest request,
String username)
throws SQLException
{
return false;
}

/**
* Returns true, CAS is an implicit method
*/
public boolean isImplicit()
{
return true;
}

/**
* No special groups.
*/
public int[] getSpecialGroups(Context context,
HttpServletRequest request)
{
return new int[0];
}


/**
* CAS authentication.
*
* @return One of: SUCCESS, BAD_CREDENTIALS, NO_SUCH_USER, BAD_ARGS
*/
public int authenticate(Context context,
String netid,
String password,
String realm,
HttpServletRequest request)
throws SQLException
{
final String ticket = request.getParameter("ticket");
final String service = request.getRequestURL().toString();
log.info(LogManager.getHeader(context, "login", " ticket: "
+ ticket));
log.info(LogManager.getHeader(context, "login", "service: "
+ service));

if (ticket != null)
{
try
{
// Determine CAS validation URL
String validate = ConfigurationManager.getProperty
("cas.validate.url");
log.info(LogManager.getHeader(context, "login", "CAS
validate: " + validate));
if (validate == null)
{
throw new ServletException("No CAS validation
URL specified. You need to set property 'cas.validate.url'");
}

// Validate ticket (it is assumed that CAS validator
returns the user network ID)
netid = validate(service, ticket, validate);
if (netid == null)
{
throw new ServletException("Ticket '" + ticket +
"' is not valid");
}

// Locate the eperson in DSpace
EPerson eperson = null;
try
{
eperson = EPerson.findByNetid(context,
netid.toLowerCase());
}
catch (SQLException e)
{
}
// if they entered a netd that matches an eperson
and they are allowed to login
if (eperson != null)
{
// e-mail address corresponds to active account
if (eperson.getRequireCertificate())
{
// they must use a certificate
return CERT_REQUIRED;
}
else if (!eperson.canLogIn())
return BAD_ARGS;

// Logged in OK.

log.info(LogManager.getHeader(context,
"type=cas-login", "type=cas"));
context.setIgnoreAuthorization(true);
eperson.setNetid(netid);
eperson.update();
context.commit();
context.setIgnoreAuthorization(false);
context.setCurrentUser(eperson);
return SUCCESS;

}

// the user does not exist in DSpace so create an
eperson
else
{
if (canSelfRegister(context, request, netid) )
{
// TEMPORARILY turn off authorisation
// Register the new user automatically
context.setIgnoreAuthorization(true);
eperson = EPerson.create(context);
// use netid only but this implies that user
has to manually update their profile
eperson.setNetid(netid);

// if you wish to automatically extract
further user details: email, first_name and last_name
// enter your method here: e.g. query LDAP
or RDBMS etc.
/* e.g.
registerUser(netid);
eperson.setEmail(email);
eperson.setFirstName(firstName);
eperson.setLastName(lastName);
*/

eperson.setCanLogIn(true);
AuthenticationManager.initEPerson(context,
request, eperson);
eperson.update();
context.commit();
context.setIgnoreAuthorization(false);
context.setCurrentUser(eperson);
return SUCCESS;
}
else
{
// No auto-registration for valid netid
log.warn(LogManager.getHeader(context,
"authenticate",
"type=netid_but_no_record, cannot auto-
register"));
return NO_SUCH_USER;
}
}

} catch (Exception e)
{
log.error("Unexpected exception caught", e);
//throw new ServletException(e);
}
}
return BAD_ARGS;
}


/**
* Returns the NetID of the owner of the given ticket, or null if the
* ticket isn't valid.
*
* @param service the service ID for the application validating the
* ticket
* @param ticket the opaque service ticket (ST) to validate
*/
public static String validate(String service, String ticket,
String validateURL)
throws IOException, ServletException
{

ServiceTicketValidator stv = null;
String validateUrl = null;

if(ticket.startsWith("ST")) {
stv = new ServiceTicketValidator();
validateUrl = casServicevalidate;
}else {
//uPortal uses this
stv = new ProxyTicketValidator();
validateUrl = casProxyvalidate;
}

stv.setCasValidateUrl(validateURL);
stv.setService(java.net.URLEncoder.encode(service));
stv.setServiceTicket(ticket);

try{
stv.validate();
} catch (Exception e) {
log.error("Unexpected
exception caught", e);
throw new ServletException(e);
}

if(!stv.isAuthenticationSuccesful()) return null;
String netid = stv.getUser();

return netid;

}


/**
* Add code here to extract user details
* email, firstname, lastname
* from LDAP or database etc
*/

public void registerUser(String netid)
throws ClassNotFoundException, SQLException
{
// add your code here
}


/*
* Returns URL to which to redirect to obtain credentials
(either password
* prompt or e.g. HTTPS port for client cert.); null means no
redirect.
*
* @param context
* DSpace context, will be modified (ePerson set) upon success.
*
* @param request
* The HTTP request that started this operation, or null if not
applicable.
*
* @param response
* The HTTP response from the servlet method.
*
* @return fully-qualified URL
*/
public String loginPageURL(Context context,
HttpServletRequest request,
HttpServletResponse response)
{
// Determine CAS server URL
final String authServer = ConfigurationManager.getProperty
("cas.server.url");
final String service = request.getRequestURL().toString();
log.info("CAS server: " + authServer);

// Redirect to CAS server
return response.encodeRedirectURL(authServer + "?service=" +
service);
}

/*
* Returns message key for title of the "login" page, to use
* in a menu showing the choice of multiple login methods.
*
* @param context
* DSpace context, will be modified (ePerson set) upon success.
*
* @return Message key to look up in i18n message catalog.
*/
public String loginPageTitle(Context context)
{
//return null;
return "org.dspace.eperson.CASAuthentication.title";
}

}


Den 23/11/2006 kl. 11.22 skrev NS Hashmi, Information Systems and
Computing:

> Hi Tonny,
>

NS Hashmi, Information Systems and Computing

unread,
Aug 24, 2015, 4:18:10 PM8/24/15
to Tonny H. Laursen, dspac...@lists.sourceforge.net
Hi Tonny,

You need to customise the validate method to meet your requirements as
stated in the patch description. The exception is being thrown when
attempting to validate the ticket on line 291: stv.validate(); the
exception implies that the ServiceTicketValidator (stv) is unable to read
the info being sent by the CAS client. You may be using an older version of
CAS as is the case with the code you supplied for dspace 1.2:
<http://wiki.dspace.org/index.php/CvtContribution>

Have you configured your JVM for secure comms (ssl)? my patch is expecting
to receive the net ID not email from the CAS server.

You could try the following to make the patch works as per the CVT code:

1. add the following imports:
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.util.Properties;

2. replace code in validate method with:

Properties p = System.getProperties();
p.put("java.protocol.handler.pkgs",
"com.sun.net.ssl.internal.www.protocol");
System.setProperties(p);
URL u = new URL(validateURL + "?ticket=" + ticket + "&service=" +
service);
BufferedReader in = new BufferedReader(new
InputStreamReader(u.openStream()));
if (in == null)
{
return null;
}
else
{
String line1 = in.readLine();
log.info("CAS validation - first line: " + line1);
String line2 = in.readLine();
log.info("CAS validation - second line: " + line2);
if (line1.equals("no"))
return null;
else
return line2;


Hope this helps.

Naveed

Tonny H. Laursen

unread,
Aug 24, 2015, 4:18:18 PM8/24/15
to dspac...@lists.sourceforge.net, Information Systems and Computing NS Hashmi
Hi,

Naveed have now helped me to find the solution. The CAS patch works
perfect with our dspace system now.
The error i got, was because in the old version of the CAS patch
(1.2.2) that we had developed, we used and URL to our CAS server that
only responds 'yes' or 'no' when it validates the SSO ticket.

In the version of the patch that Naveed have developed it's need an
answer in XML format.
In our dspace.cfg file we have now changed the following:

From:
cas.validate.url=https://xxx.xxx.xx/validate

To:
cas.validate.url=https://xxx.xxx.xx/serviceValidate

Thanks to Naveed for maintaining the CAS code,

Regards,
Tonny

Den 23/11/2006 kl. 13.04 skrev NS Hashmi, Information Systems and
Computing:

NS Hashmi, Information Systems and Computing

unread,
Aug 24, 2015, 4:18:20 PM8/24/15
to Tonny H. Laursen, dspac...@lists.sourceforge.net
Hi Tonny,

Thanks for testing the patch.

Regards,

Naveed
Reply all
Reply to author
Forward
0 new messages