Tuesday, 6 October 2009

Upgrade to shibboleth-idp2.1.3

Shibboleth-idp 2.1.3 brings some great news, like properties now working inside attribute-resolver.

Unfortunately this upgrade should be taken seriously: I just unpacked the src, noticed a minor glitch from my previous setup (StoredID requires now just one dependency, no more), then suddently all connection from IE were broken with a white page and the following trace in the logs:

 at java.lang.Thread.run(Thread.java:619) [na:1.6.0_12]
10:07:05.583 - ERROR [edu.internet2.middleware.shibboleth.idp.authn.provider.Use
rnamePasswordLoginServlet:143] - Unable to redirect to login page.
org.apache.jasper.JasperException: Exception in JSP: /login.jsp:10

7:     LoginContext loginContext = HttpServletHelper.getLoginContext(HttpServletHelper.getStorageService(application),
8:                                                                   application, request);
9:                                                                   
10:     EntityDescriptor entityDescriptor = HttpServletHelper.getRelyingPartyMetadata(loginContext.getRelyingPartyId(),
11:                                                    HttpServletHelper.getRelyingPartyConfirmationManager(application)); 
12:                                                     
13:     Session userSession = HttpServletHelper.getUserSession(request);

As Mozilla Firefox run great, I double checked configuration files until, out of desperation, upgraded tomcat from version 5.5 to 6. Issue solved.

Frankly speaking, it was written at Preparing Apache Tomcat for the Shibboleth Identity Provider, but this issue arises with Debian: with RedHat no trouble.

Now the fun part: property file in attribute-resolver.xml: it is now possible to modify in handler.xml the attribute-resolver.xml definition:
<Service id="shibboleth.AttributeResolver"
             xsi:type="attribute-resolver:ShibbolethAttributeResolver">
        <ConfigurationResource file="/opt/shibboleth-idp/conf/attribute-resolver.xml" xsi:type="resource:FilesystemResource" >
        <ResourceFilter xsi:type="PropertyReplacement"
                        xmlns="urn:mace:shibboleth:2.0:resource"
                        propertyFile="/opt/shibboleth-idp/conf/my.properties"/>
        </ConfigurationResource>
    </Service>

where my.properies is:
bind_dn = cn=admin,dc=test,dc=com
bind_pw = WN./NHmh

which translates in attribute-resolver.xml:
 <resolver:DataConnector id="ldap1" xsi:type="LDAPDirectory" xmlns="urn:mace:shibboleth:2.0:resolver:dc"
        ldapURL="ldap://localhost" 
 baseDN="ou=people,dc=test,dc=com" 
 principal="${bind_dn}"
        principalCredential="${bind_pw}"
 useStartTLS="true">
        <FilterTemplate>
            <![CDATA[
                (uid=$requestContext.principalName)
            ]]>
        </FilterTemplate> 
    </resolver:DataConnector>

More examples at Dealing with Sensitive Configuration Information

Tuesday, 29 September 2009

Enable tomcat manager to reload shibboleth

It would be useful to be able to reload shibboleth without having to stop and restart tomcat. It is actually possible, but it is necessary to enable the manager servlet, which requires some steps.

First of all, install
sudo apt-get install tomcat5.5-admin

Then configure apache to handle /manager url though mod_ajp: add the following line in the ssl virtual host (then reload apache)
ProxyPass /manager ajp://localhost:8009/manager

Change permission to manager deployment fragment so it could be executed by tomcat5 user:
sudo chmod +x /etc/tomcat5/conf/Catalina/localhost/manager

Then create a principal able to access the manager web page: edit /etc/tomcat5.5/tomcat-users.xml by adding a user like:
<user username="admin" password="secret" roles="standard,manager"/>
(role admin is necessary to access to manager)

Then you can use the commands listed at:
http://tomcat.apache.org/tomcat-5.5-doc/manager-howto.html#Introduction

For instance, to reload shibboleth:
https://idp.server.com/manager/reload?path=/idp

Thursday, 17 September 2009

Server side sort with OpenLDAP2.4.18

OpenLDAP2.4.18 sports server side sorting (RFC 2891).

First of all, during configuration, sss should be enabled:
./configure --enable-hdb=yes --enable-sssvlv --enable-ppolicy --with-cyrus-sasl --with-tls=openssl

Then in slapd.conf, overlay has to be enabled:
overlay sssvlv
This line has to be added either in the global part or inside a backend directive.

Then, a ldapsearch can test the feature:
/usr/local/bin/ldapsearch -h localhost -x -E 'sss=cn' 'sn=m*' cn
if there is an attribute with a ordering rule.

If not, an error arises:
# extended LDIF
#
# LDAPv3
# base  with scope subtree
# filter: sn=m*
# requesting: cn 
# with server side sorting control
#

# search result
search: 2
result: 18 Inappropriate matching
text: serverSort control: No ordering rule

# numResponses: 1

You can add ordering rules to schemas: for instance to add ordering rules to sn, modify sn entry in core.schema as follows:
attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
 DESC 'RFC2256: last (family) name(s) for which the entity is known by'
 ORDERING caseIgnoreOrderingMatch
 SUP name )

This time ldapsearch returns:
# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.474 false MIQAAAADCgEA
sortResult: (0) Success

# numResponses: 4602
# numEntries: 4601

Monday, 14 September 2009

Install shibboleth DiscoveryService1.1.1

Instructions are ok, but I tripped on some pitfalls.

1) when deploying service, service name has to be
discovery
, so the URL in tomcat should be /discovery and deployment fragment in /etc/tomcat5.5/Catalina/localhost should look like:

<Context docBase="/opt/shibboleth-ds/war/discovery.war"
privileged="true"
antiResourceLocking="false"
antiJARLocking="false"
unpackWAR="false"
swallowOutput="true" />

this should be obvious from war name, but not to me.
2) before doing install.sh I had to remove servlet-api-2.3.jar from directory /lib. Otherwise I had an error in tomcat:
INFO:
validateJarFile(/var/lib/tomcat5.5/webapps/discovery/WEB-INF/lib/servlet-api-2.3.jar)
- jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class:
javax/servlet/Servlet.class
3) no log starts, unless you hit the url of the discoveryService, which is https://my-server.com/discovery/WAYF
4) session initiator of shibboleth-sp should look like:

<SessionInitiator acsByIndex="false" type="Chaining"
Location="/discovery" id="discovery" relayState="cookie">
<SessionInitiator type="SAML2" defaultACSIndex="1"
template="bindingTemplate.html"/>
<SessionInitiator type="Shib1" defaultACSIndex="5"/>
<SessionInitiator type="SAMLDS"
URL="https://my-server.com/discovery/WAYF"/>
</SessionInitiator>

With the SP packeged with debian/lenny, i had to add
acsByIndex="false" in the first line.
5) with the same shibboleth-sp I had to regenerate metadata from Shibboleth.sso/Metadata, as it was missing:

<md:Extensions>
<DiscoveryResponse
xmlns="urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol"
Location="http://bacedifo.cesia.unimo.it/Shibboleth.sso/discovery"
index="1"/>
</md:Extensions>

before the keys section (<md:KeyDescriptor use="signing">), inside md:SPSSODescriptor section.

Wednesday, 2 September 2009

Query Shibboleth2 Attribute Authority without WebSSO

First of all, please read the illuminating thread on shibboleth mailing list titled How can I only use AA of Shibboleth IdP, specially Tom Scavo's answer.

In this post I would like to show how to query the Shibboleth AA remotely from command line. This query can be well authomated in a kind of web service, which offers the informations Shibboleth gathers from different sources exactly as offered to Shibboleth SP.

The tool used is curl. It is necessary:
* craft a valid attribute request to send to shibboleth-idp
* relax security to accept queries authentication-less.

Actually authentication works as in Shibboleth-SP1.3 attribute query: requester is authenticated with x509 client certificates.

Create a valid attribute request with curl


sudo curl -v -K .curlrc

with
 $ cat .curlrc
url =
"https://idp.site.com:8443/idp/profile/SAML1/SOAP/AttributeQuery"
cert = "/etc/ssl/certs/client.pem"
key = "/etc/ssl/private/client.key"
cacert = "/etc/ssl/certs/ca-chain.pem"
data-binary = @soap.xml

and

$ cat soap.xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
IssueInstant="2009-06-10T07:21:37Z" MajorVersion="1" MinorVersion="1"
RequestID="_37fd92205b573e2b52d1a27e2e3b2192">
<samlp:AttributeQuery
Resource="https://moodle-idem.unimore.it/shibboleth">
<saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
<saml:NameIdentifier
Format="urn:mace:shibboleth:1.1:nameid-format:unspecified">the_username</saml:NameIdentifier>
</saml:Subject>
</samlp:AttributeQuery>
</samlp:Request>
</S:Body>
</S:Envelope>

Please note the_username is the principalName in the IdP Attribute Resolver.

Configurations changes on the IdP



You should instruct IdP:

  • Accept Attribute query without former authentication

  • Map the nameid in the query with a local principal


The first is done in relying-party.xml: just comment out the lines about samlsec:Replay e samlsec:IssueInstant from SecurityPolicy shibboleth.SAML1AttributeQuerySecurityPolicy (of course IssueInstant is just not to have to forge the correct datetime, if you script it you could enforce this control).

The second is done in attribute-resolver.xml: modify line

<resolver:PrincipalConnector xsi:type="Transient" xmlns="urn:mace:shibboleth:2.0:resolver:pc" id="saml1Unspec"
nameIDFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />

to

<resolver:PrincipalConnector xsi:type="Direct" xmlns="urn:mace:shibboleth:2.0:resolver:pc" id="direct"
nameIDFormat="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" />

It should be safe doing that because there are three nameId format, the 2.0 is used by Shibboleth-sp2.0 (which actually does not request attribute query, anyhow), the 1.0 is used by Shibboleth-sp1.3, so 1.1 format should be unused, unless othe saml clients do. In the latter case, I have no idea how to solve the issue.

Metadata


In metadata you should add a SP-like entry with the client certificate used by curl. Attribute filter applies rule according to this fake SP-entry.

Thursday, 14 May 2009

ruby ResolverScriptAttributeDefinition in shibboleth2.1

As advertised at shibboleth2.1 can leverage scripting languages as jruby via jsr223.

Unfortunately documentation just covers ecmascript, no examples for ruby.

Here follows a working example:


<resolver:AttributeDefinition id="example3" xsi:type="Script"
language="ruby" xmlns="urn:mace:shibboleth:2.0:resolver:ad">
<resolver:Dependency ref="ldap" />
<resolver:Dependency ref="example2" />
<resolver:Dependency ref="example1" />
<resolver:AttributeEncoder xsi:type="SAML1String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="urn:mace:unimore.it:attribute-def:example3" />
<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
name="urn:mace:unimore.it:attribute-def:example3" friendlyName="example3" />
<Script>
<![CDATA[
include Java

include_class 'edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute'

$example3 = BasicAttribute.new("example3")
[$example1, $example2].each do |array|
array.get_values.each do |v|
$example1.get_values.add v
end
end
]]>
</Script>
</resolver:AttributeDefinition>


In this example values from example1 and example2 fields are merged in the new example3 attribute.

Key point to note are:
* variables are exported from shibboleth as globals ($ prefix);
* as import_package did not work for me, just including edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute is enought;
* values of attribute are of type Java::JavaUtil::ArrayList. I'm not really sure normal ruby array operation work (maybe yes);
* puts can be useful with aacli.sh: it prints on the console.

Friday, 10 April 2009

JRuby via jsr223

jsr223 allows embedding jruby code in java.

Unfortunately, at least on Debian lenny, setup requires some work.

First of all, be sure to install java1.6, for example with sun-java6-jdk package.

Then two more downloads are required:
* jruby, for instance jruby1.1.6
* jruby-engine-1.1.6.zip
Version of jruby engine must match jruby version.

Unpack Jruby, define $JRUBY_HOME to the expanded directory and have PATH=$PATH:$JRUBY_HOME/bin.

Unpack jruby-engine-*.zip.

Include in classpath jruby.jar and jruby-engine.jar from the /lib dir of the unpacked tarball.

Compile javacode as usual with javac; to run code, it could be necessary to add a -cp .:./jruby.jar:./jruby-engine.jar switch to java.

It should be possible to use jsr223-engines tarball instead of jruby-engine-*, but I tried with no luck. jruby1.0 is a deb package, but installing it didn't help, and I feared it could introduce path problems so I removed it.