Alfresco 4 SSO

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

09.05.2013 Alfresco 4.

0 Share single sign on (SSO)

Samarko Search

Alfresco PHP MySQL Internet Design Gadgets


About Contacts

SUNDAY, SEPTEMBER 25, 2011

Alfresco 4.0 Share single sign on (SSO)


As mentioned earlier, Alfresco has many built-in
authorization mechanisms. However, Alfresco has not
native support for transparent authentication (SSO,
single-sign-on). Therefore, the challenge is: to create an
authorization subsystem that enables users to enter
Alfresco without a password using NTLM domain
authentication. This subsystem must be running
Windows 7, Vista, XP, be safe and secure. Read more to
know how this problem was solved.

You can download the source code in archive.

The proposed scheme of transparent SSO authentication in Alfresco is shown in


Figure:

As the working mechanism of Alfresco authorization you should select External. For
this in file C:\Alfresco\tomcat\shared\classes\alfresco-global.properties you should set

blog.samarko.com/2011/09/alfresco-40-share-single-sign-on-sso.html 1/7
09.05.2013 Alfresco 4.0 Share single sign on (SSO)

the following properties:

authentication.chain=external1:external,alfrescoNtlm1:alfrescoNtlm
external.authentication.enabled=true
external.authentication.proxyHeader=X-Alfresco-Remote-User
external.authentication.proxyUserName=

To set the interaction between the applications Alfresco and Share to be hold by
cookies, in a file you should write:

<config evaluator="string-compare" condition="Remote">


<remote>
<endpoint>
<id>alfresco-noauth</id>
<name>Alfresco - unauthenticated access</name>
<description>Access to Alfresco Repository WebScripts that do
not require authentication</description>
<connector-id>alfresco</connector-id>
<endpoint-url>http://localhost:8080/alfresco/s</endpoint-url>
<identity>none</identity>
</endpoint>
<connector>
<id>alfrescoCookie</id>
<name>Alfresco Connector</name>
<description>Connects to an Alfresco instance using cookie-
based authentication</description>
<class>org.springframework.extensions.webscripts.connector.Alf
rescoConnector</class>
</connector>
<endpoint>
<id>alfresco</id>
<name>Alfresco - user access</name>
<description>Access to Alfresco Repository WebScripts that
require user authentication</description>
<connector-id>alfrescoCookie</connector-id>
<endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url
>
<identity>user</identity>
<external-auth>true</external-auth>
</endpoint>
</remote>
</config>

If you do not, Share can not communicate


with the repository of Alfresco.

Now, Alfresco will trust the transferred to it


server variable RemoteUser. To generate this
variable, create a subsystem of the Apache
modules. As the unit responsible for the
domain transparent user authentication,
choose sspi_auth_module.

To plug it in, write in Apache's configuration


file (httpd.conf):

LoadModule sspi_auth_module modules/mod_auth_sspi.so

At the same time, register in the httpd.conf configuration that will be useful in the
future:

LoadFile "C:/Perl/bin/perl512.dll"
LoadModule perl_module modules/mod_perl.so
Listen 10.0.20.245:80
ServerName vm-lysenko

<VirtualHost 10.0.20.245:80>
ServerName vm-lysenko

2/7
09.05.2013 Alfresco 4.0 Share single sign on (SSO)
DocumentRoot "C:\alf"
UseCanonicalName Off

PerlModule Apache2::RequestRec

RedirectMatch ^/$ /share/


RedirectMatch ^/alfresco$ /alfresco/
RedirectMatch ^/share$ /share/
RedirectMatch ^/login$ /login/

<Proxy ajp://127.0.0.1:8009/login/>
Order deny,allow
Deny from none
Allow from all
</Proxy>

<Proxy ajp://127.0.0.1:8009/alfresco/>
Order deny,allow
Deny from none
Allow from all
</Proxy>

<Proxy ajp://127.0.0.1:8009/share/>
Order deny,allow
Deny from none
Allow from all
PerlFixupHandler Apache2::SetRemoteUser
</Proxy>

ProxyPass /login/ ajp://127.0.0.1:8009/login/


ProxyPassReverse /login/ ajp://127.0.0.1:8009/login/
ProxyPass /alfresco/ ajp://127.0.0.1:8009/alfresco/
ProxyPassReverse /alfresco/ ajp://127.0.0.1:8009/alfresco/
ProxyPass /share/ ajp://127.0.0.1:8009/share/
ProxyPassReverse /share/ ajp://127.0.0.1:8009/share/

<Location "/login/login.jsp">
AuthName "Tomcat"
AuthType SSPI
SSPIAuth On
SSPIPackage NTLM
SSPIAuthoritative On
SSPIOfferBasic Off
SSPIOmitDomain On
SSPIUsernameCase lower
# SSPIPerRequestAuth Off
# SSPIBasicPreferred
# SSPIUsernameCase lower
require valid-user
</Location>
</VirtualHost>

From the above settings it is clear, that Apache serves as a proxy, and passes
through all the requests from the user to the Alfresco Share. Every time we refer to
Share, we use PerlFixupHandler Apache2:: SetRemoteUser, to set the variable
RemoteUser. To set this variable, use this perl-script: (in folder
c:\Perl\site\lib\Apache2\ file SetRemoteUser.pm)

package Apache2::SetRemoteUser;

use strict;
use warnings;

use CGI::Cookie;
use Apache2::Const -compile => qw(OK);
use Apache2::Connection;
use Apache::DBI;

sub handler {
my $r = shift;

my $session_value = "";

blog.samarko.com/2011/09/alfresco-40-share-single-sign-on-sso.html 3/7
09.05.2013 Alfresco 4.0 Share single sign on (SSO)

my $raw_cookie = $r->headers_in->{'Cookie'} || '';


if ($raw_cookie ne '') {
my %cookie = CGI::Cookie->parse($raw_cookie);
if (exists $cookie{'JSESSIONID'}) {
$session_value = $cookie{'JSESSIONID'}->value || "unknown-sess
ion";
}
}

my $ip = $r->connection->remote_ip() || "unknown-ip";


my $browser = $r->headers_in->{ 'User-Agent' } || "unknown-
agent";
my $authorization = $r->headers_in->{ 'Authorization' } || "not-a
uth";

my $url = $r->uri || "unknown-url";

my $dbh = DBI->connect("DBI:mysql:sessions:localhost:3306", "sessi


on_user", "session_password", {
PrintError => 1, # warn( ) on errors
RaiseError => 0, # don't die on error
AutoCommit => 1, # commit executes immediately
}
) or die "Cannot connect to database: $DBI::errstr";

my $do_sql = "SELECT username FROM session WHERE unique_value = MD


5('" . $session_value . $ip . $browser . "')";
my $sth = $dbh->prepare($do_sql);
$sth->execute( );

my $result = $sth->fetchrow_hashref();
my $u_name = $result->{'username'} || "";
$dbh->disconnect( ); # NOOP under Apache::DBI

if ($u_name ne "") {
$r->user($u_name);
}
return Apache2::Const::OK;
}
1;

This script checks if there is a registered session with the provided user name. If
the session exists, the remoteUser sets up. As a place of sessions storage selected the
MySQL database. The structure of sessions table is:

CREATE TABLE `session` (


`session_ID` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) DEFAULT NULL,
`session_value` varchar(50) DEFAULT NULL,
`unique_value` varchar(255) DEFAULT NULL,
`session_date` datetime DEFAULT NULL,
PRIMARY KEY (`session_ID`)
) ENGINE=InnoDB

Perl-script only reads the data from this table. The jsp-app Login, which is
mentioned in the httpd.conf settings, records there. This application must be
deployed on the same tomcat server, as applications Alfresco and Share. The main
part of it is the file login.jsp, which is responsible for "recognition" of users and
recording sessions to the database.

<%@ page session="true" %>


<%@ page import="java.io.*" %>
<%@ page import="java.sql.*;" %>
<%

String remoteUser = request.getRemoteUser();


String returnPath = request.getParameter("r");

Boolean login = false;


Integer error_status = 0;

4/7
09.05.2013 Alfresco 4.0 Share single sign on (SSO)

if (remoteUser != null) {

String driver = "org.gjt.mm.mysql.Driver";


Class.forName(driver).newInstance();

Connection con = null;


ResultSet rst = null;
Statement stmt = null;
PreparedStatement pstmt = null;

String found_name="";
String sessionValue="";
String sql="";

String ip = request.getRemoteAddr();
String browser = request.getHeader("User-Agent");

Cookie cookies[] = request.getCookies();

if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (((String)cookies[i].getName()).equals("JSESSIONID")) {
sessionValue = cookies[i].getValue();
}
}
}

try {
String session_url = "jdbc:mysql://localhost:3306/sessions";
String alfresco_url = "jdbc:mysql://localhost:3307/alfresco";

con = DriverManager.getConnection(alfresco_url, "root", "root");


sql = "SELECT authority FROM alf_authority WHERE authority = '" +
remoteUser + "'";
stmt = con.createStatement();
rst = stmt.executeQuery(sql);
while(rst.next()){
found_name = rst.getString(1);
}
con.close();
stmt.close();

if (sessionValue.equals("")) {
error_status = 1;
}

if (!(found_name.equals(remoteUser) && !found_name.equals(""))) {


error_status = 2;
}

if (error_status.equals(0)) {
con=DriverManager.getConnection(session_url, "session_user", "se
ssion_password");
sql = "DELETE FROM session WHERE (session_value = '" + sessionVa
lue + "') OR (username = '" + remoteUser + "')";
pstmt = con.prepareStatement(sql);
pstmt.executeUpdate();

sql = "INSERT INTO session SET session_value = '" + sessionValue


+ "', username = '" + remoteUser + "', session_date = NOW(), unique_v
alue = MD5('" + sessionValue + ip + browser + "')";
pstmt = con.prepareStatement(sql);
pstmt.executeUpdate();

login = true;
} else {
login = false;
}

rst.close();
pstmt.close();
con.close();
} catch(Exception e){
blog.samarko.com/2011/09/alfresco-40-share-single-sign-on-sso.html
09.05.2013 Alfresco 4.0 Share single sign on (SSO)
System.out.println(e.getMessage());
}

if (login) {
if (returnPath != null) {
response.sendRedirect(returnPath);
} else {
response.sendRedirect("/share/page/user/" + remoteUser + "/dashb
oard");
}
} else {
if (error_status.equals(1)) {
response.sendRedirect("login.jsp");
} else {
response.sendRedirect("could-not-login.jsp");
}
}
}
%>

Login.jsp checks if there is a specific user in the database of Alfresco. This is


necessary in order to allow only the domain users that are registered in Alfresco. Also,
this script writes to the table a unique user sessions data that are necessary for
unambiguously identifying: browser, IP, etc.

Each time the Share application is not identified the user, it produces a page with a
login and password form. In this page we need to implement a handler that instead
of issuing a login form will redirect to our domain login script. To do this, you need to
add the line in file slingshot-login.ftl:

<script>
window.location.href = "/login/login.jsp?r=" + window.location.href;
</script>

The r parameter is needed in order to return the user to the page, that it wanted to
refer.

Now that you have installed all the additional subsystems, you must correctly
configure Tomcat. In the server.xml file should be registered two connectors with the
following parameters:

<Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"


connectionTimeout="20000"
redirectPort="8443" tomcatAuthentication="false"
emptySessionPath="true" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"
tomcatAuthentication="false"
emptySessionPath="true" />

Connector on port 8009 is required for Apache proxy. For security purposes, you
must close the ports 8080 and 8009 from outside access, only local server must have
access to them. All external requests takes on Apache on port 80. If you do not close
the mentioned ports, an attacker could fool the system and log into any desired user.

Parameter tomcatAuthentication = "false" need to turn off the built-in Tomcat


authentication mechanisms, because we do not need them. Parameter
emptySessionPath = "true" is needed to ensure that the session, formed in one
application, will be acted in another. If this option is not set, the session of Share will
not operate in the Alfresco application, to say nothing of our Login application.
Described procedures for the authorization required to Login application could freely
transfer session to Share application.

You can download the source code in archive.

blog.samarko.com/2011/09/alfresco-40-share-single-sign-on-sso.html 6/7
09.05.2013 Alfresco 4.0 Share single sign on (SSO)

0 2

Alfresco

You may also like:

Alfresco Desktop Recom m endations for Floating block using Forbid site to load in
actions in CIFS Google im ages indexing JQuery fram es (or ifram es)

HFS, a free HTTP file Opening port in the Perform ing secure FTP- How to install counter on
service Com odo Firew all connection over SSH any w eb-application

0 comments 0

Leave a message...

Best Community Share

No one has commented yet.

C o m m e n t fe e d Su b s cri b e vi a e m a i l

Older Post Home Newer Post

Sergey Lysenko on Add to circles

blog.samarko.com/2011/09/alfresco-40-share-single-sign-on-sso.html 7/7

You might also like