Search code examples
javasingle-sign-onsaml-2.0shibbolethopensaml

OIOSAML: Service endpoint settings issue


I wrote a simple system with SP-initiating Web SSO scenario based on OIOSAML. To test the system, I deployed it on the remote host.

However AssertionConsumerServiceURL, where I specified URL, on which Shibboleth idP (idP based on Shibboleth) should return the answer is not called.

SAMLAssertionConsumer - just a simple servlet, like this:

@WebServlet("/saml/consumer")
public class SAMLAssertionConsumer extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println(new Date() + " incoming AuthResponse");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Yes, it worked");

        System.out.println(new Date() + " incoming AuthResponse");
    }
}

For a begin with, I just need to make sure that the response comes.

My web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
    metadata-complete="false"     
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >

    <display-name>OIOSAML-J</display-name>

    <listener>
        <listener-class>dk.itst.oiosaml.sp.service.session.SessionDestroyListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>SAMLDispatcherServlet</servlet-name>
        <servlet-class>dk.itst.oiosaml.sp.service.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SAMLDispatcherServlet</servlet-name>
        <url-pattern>/saml/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>dk.itst.oiosaml.sp.service.SPFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/sp/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

My oiosaml-sp.properties:

# Properties used by oiosaml-j

# Reference to the location of the certificate used for signing SAML documents with - relative to ${oiosaml.home}
oiosaml-sp.certificate.location=./certificate/keystore

# Opaque/encrypted password to the certificate used for signing SAML documents
oiosaml-sp.certificate.password=some_password

# Required authentication level. 2=password, 3=certificate
oiosaml-sp.assurancelevel=2

# Name of the meta data file for the current service provider - overrides setting in brs-common.properties
common.saml2.metadata.sp.filename=SPMetadata.xml

# URI References to the current service provider
oiosaml-sp.uri.home=

# Whether to validate server certificates. Set to false in production.
# Used for artifact resolution.
oiosaml-sp.resolve.ignorecert=true

# Artifact resolution username and password. Only used the artifact profile is active.
oiosaml-sp.resolve.username=rolf.trifork.com
oiosaml-sp.resolve.password=rolf.trifork.com

Generated AuthnRequest:

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
                     AssertionConsumerServiceURL="http://ip-of-remote-system-here:8080/saml/consumer"
                     Destination="http://ip-of-identity-provider-here/idp/profile/SAML2/Redirect/SSO" ForceAuthn="false"
                     ID="_31e...341d322d1d" IsPassive="false"
                     IssueInstant="2014-07-11T10:24:43.852Z"
                     ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Version="2.0">
    <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://ip-of-remote-system-here:8080</saml2:Issuer>
</saml2p:AuthnRequest> 

There is some JSP-page private.jsp, I make a request to it:

http://ip-of-remote-system-here:8080/sp/private.jsp

After this request I redirected to login page of identity provider:

http://ip-of-identity-provider-here/idp/Authn/CommonLogin

Enter a couple login/password and.. nothing. Opens page with description of some common error:

http://ip-of-identity-provider-here/idp/Authn/UsernamePasswordLogin

error

An error occurred while request processing.

Does not work and my servlet SAMLAssertionConsumer, the console is clear. But if I make request to my servlet SAMLAssertionConsumer direct:

http://ip-of-remote-system-here:8080/saml/consumer

Then it works. Of course.

I would like to know how to properly configure the the assertion consumer service. That is the part of the SP-metadata, where I specify the assertion consumer.

<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:esia="urn:esia:shibboleth:2.0:mdext" entityID="http://ip-of-remote-system-here:8080">
...
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"  Location="http://ip-of-remote-system-here:8080/saml/consumer" ResponseLocation="http://ip-of-remote-system-here:8080/saml/consumer"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://ip-of-remote-system-here:8080/saml/consumer" index="0" isDefault="true"/>

Solution

  • The problem was different. Was used incorrect keystore. Now everything is OK.

    Initially, I assumed that entityID attribute must refer to a domain name, which specified in attributes Location. However, it is not. It just must be unique and it is better to use domain name for that.

    UnderstandingShibboleth, EntityNaming:

    Shibboleth identity and service providers are used in SAML deployments, and as such, they are assigned a unique name known as an "entityID".

    Metadata for the OASIS Security Assertion Markup Language (SAML)V2.0, 2.3.2 Element :

    entityID [Required] -

     Specifies the unique identifier of the SAML entity whose metadata is 
     described by the element's contents.
    

    UnderstandingShibboleth, EntityNaming:

    Strongly recommended NOT to use the physical hostname of a server running Shibboleth as the entityID. As time passes, things get moved and that deployment may not always live on the same box.

    Additionally there may be multiple logical deployments of Shibboleth on a single physical server, each requiring their own unique entityID, so using the server's name doesn't scale beyond a single one.

    In the sandbox can be use physical addresses.