Tuesday, August 20, 2013

Apache Syncope tutorial - part IV

In the first tutorial on Apache Syncope, we showed how to deploy Syncope to Apache Tomcat, using MySQL as the internal storage mechanism. In the second and third tutorials, we showed how to import some users and roles into Syncope from database and directory backend resources. In this tutorial, we will show how an external client can query Syncope's REST API for the purposes of authentication and authorization. This tutorial assumes that Syncope is set up as described in tutorial I, and that Users + Roles have been imported as per tutorials II and III.

1) Syncope's REST API

Apache Syncope exposes its functionality via a rich REST API. Apache Syncope 1.1 features a new REST API, which is powered by Apache CXF. The new API has been created with the aim of applying RESTful best practices.

2) Querying Syncope's REST API

I've created some simple test-cases (hosted on github) based around a CXF SOAP client/service invocation, which show how to use Syncope's REST API for authentication and authorization.

a) Authentication

The Authentication test uses Syncope as an IDM for authentication. A CXF client sends a SOAP UsernameToken to a CXF Endpoint. The CXF Endpoint has been configured to validate the UsernameToken via the SyncopeUTValidator, which dispatches the username/passwords to Syncope for authentication via Syncope's REST API. Run the test via:
  • git clone git://github.com/coheigea/cxf-syncope.git
  • cd cxf-syncope
  • mvn test -Dtest=AuthenticationTest
Look at the console output to see how the CXF service dispatches the received Username/Password to Syncope for authentication. 

b) Authorization

The Authorization test uses Syncope as an IDM for authorization. It exploits the fact that we synchronized User's Roles into Syncope in tutorial IV. A CXF client sends a SOAP UsernameToken to a CXF Endpoint. The CXF Endpoint has configured the SyncopeRolesInterceptor, which authenticates the Username/Password to Syncope as per the authentication test. If authentication is successful, it then gets the roles of the user and populates a CXF SecurityContext with the user's name + roles.

The CXF Endpoint has also configured the SimpleAuthorizingInterceptor, which reads the current Subject's roles from the SecurityContext, and requires that a user must have role "boss" to access the "doubleIt" operation ("alice" has this role, "bob" does not). Run the test via:
  • git clone git://github.com/coheigea/cxf-syncope.git
  • cd cxf-syncope
  • mvn test -Dtest=AuthorizationTest


12 comments:

  1. Hi Colm,

    thanks for your excellent article and source code example. In Apache Syncope project I have seen there is a module called syncope-client.
    It seams it implements client Java API to access to Syncope wrapping rest calls.

    What's the best way you suggest to integrate with syncope? REST API or syncope-client?

    Thanks,
    Denis.

    ReplyDelete
  2. Hi Denis,

    I would say that if the "syncope-client" module meets your needs then use that. In the source code I linked to on github, it just uses the REST API directly, mainly to show how a third party can invoke on Syncope.

    Colm.

    ReplyDelete
  3. Hi i am working with identity and access control and just want to know how can i use syncope in my application to implement ws-federaion with single signOn.

    ReplyDelete

  4. Syncope does not offer WS-Federation or SSO. Instead you should look at Apache CXF Fediz:

    http://cxf.apache.org/fediz

    Colm.

    ReplyDelete
    Replies
    1. Thanks Colm so this Apache CXF will do this for me means it will implement ws-federation for me.

      Delete
  5. Hi Colm,

    I've tried this example but github.com/coheigea/cxf-syncope.git is no longer avalaible. I got the code from github.com/coheigea/testcases/tree/master/apache/cxf/cxf-syncope but, when i execute mvn test -Dtest=AuthenticationTest, it throws me an error about the pom.xml file: "Non-parseable POM /home/ubuntu/cxf/pom.xml: Expected root element 'project' but found 'html' " Any help here?

    Thanks a lot,

    Javi.

    ReplyDelete
  6. What happens if you do "git clone https://github.com/coheigea/testcases.git", and then a "mvn clean install" from the apache/cxf directory?

    Colm.

    ReplyDelete
  7. Hi Colm,

    I followed the steps 1-3 of the tutorial, and managed to setup and load the databases to Syncope. But the AuthenticationTest does not work for me. It sends "alice:security" in the HTTP Authorization parameter, and Syncope returns HTTP 401. It only works if I send "admin:password" instead. I am not sure if this is the right way to use the Syncope REST API. Is not it possible that the Authorization HTTP param should be used to authenticate to Syncope, and the user:password to be queried goes somewhere in the HTTP body?

    Thanks,
    Ivan

    ReplyDelete
  8. Hi Ivan,

    Are you sure that user "alice" has been synced into Syncope? So for example, when you log onto the Syncope UI, do you see the user "alice" in the Users tab?

    Colm.

    ReplyDelete
  9. Hi Colm,

    I guess the users are correctly synchronized to Syncope. Please have a look at this:

    curl -u admin:password http://localhost:8080/syncope/cxf/users?username=alice

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <user>
    <attributes>
    <attribute>
    <readonly>false</readonly>
    <schema>surname</schema>
    <value>smith</value>
    </attribute>
    </attributes>
    <derivedAttributes/>
    <id>152</id>
    <propagationStatuses/>
    <resources/>
    <virtualAttributes/>
    <creationDate>2014-07-06T00:29:41+02:00</creationDate>
    <failedLogins>14</failedLogins>
    <memberships>
    <membership>
    <attributes/>
    <derivedAttributes/>
    <id>100</id>
    <propagationStatuses/>
    <resources/>
    <virtualAttributes/>
    <resources/>
    <roleId>100</roleId>
    <roleName>boss</roleName>
    </membership>
    <membership>
    <attributes/>
    <derivedAttributes/>
    <id>101</id>
    <propagationStatuses/>
    <resources/>
    <virtualAttributes/>
    <resources/>
    <roleId>101</roleId>
    <roleName>employee</roleName>
    </membership>
    </memberships>
    <password>C8A14DACDCB64CEAD6D7766A9DD02BBD1D57FFCF</password>
    <status>active</status>
    <username>alice</username>
    </user>

    But then the /user/self (what your test is doing) is not working for me:

    curl -u alice:security http://localhost:8080/syncope/cxf/users/self

    ... <body><h1>HTTP Status 401 - User alice not authenticated</h1>...

    ReplyDelete
  10. Hi Colm. Likely this is a bug in Syncope. During testing it I found a few strange issues. Please dont waste time with it. Thanks for the excellent tutorials, I followed many of them.

    ReplyDelete
  11. Thank you for valuable tutorials on syncope.

    ReplyDelete