Workflow Name: amset1authentication#

Constituent Services: InitAuthentication; AuthenticationService#

Workflow Description#

This is just about the simplest Alfresco workflow and forms the basis of the method by which Alfresco secures all its SOAP over HTTP Web services. In short, the workflow is initialised by receiving a message that contains the username and password of an Alfresco administration account. These are used to call the startSession operation in the Authentication Service which returns three strings: the username submitted in the initialisation message, a security ticket, and a Java sessionid. The security ticket is used to validate further calls to Alfresco Web services. It is valid for a default period of 5 minutes or until cancelled by calling the endSession operation which takes the ticket string as a parameter.

Note that by default the initialisation Web service request goes over the wire completely unsecured. An HTTPS (SSL) link will have to be created to fill this teensy weensy security hole.

Technical Notes#

Platform: GlassFishESB V2, NetBeans IDE 6.1 (including BPEL Designer, implementing WS-BPEL 2.0) Java: 1.6.0_10; Java HotSpot(TM) Client VM 11.0-b15 System: Windows XP version 5.1 running on x86; Cp1252; en_GB (nb).

Alfresco Labs 3.1 running on remote server, 64-bit Java 1.6.0_13, Tomcat 6 on Red Hat Enterprise Linux 5.

The Process#

Figure 1.1. AuthenticationProcess.bpel Netbeans process diagram (elements labelled)


A. InitAuthentication Web service: a 'myRole' partner link, messages posted into this service.
B. External Alfresco Authentication Service.
1. Message containing Alfresco admin username and password(!) sent to InitAuthentication, which initializes run.
2. Admin username and password from incoming InitAuthentication message assigned to corresponding variables in Authentication startSession() operation.
3. Invoke Authentication Service startSession() operation.
4. Assign value of ticket string to endSession() variable.
5. Invoke Authentication Service endSession().
6. Assign variables to InitAuthentication service reply variable.
7. Reply to InitAuthentication service.

The BPEL Script#

The workflow scripts will be available from the AMSeT SourceForge repository so they won't all be reproduced here on the wiki. This first one might help those interested in the NetBeans BPEL Designer to see how the process diagram relates to the BPEL script.

Code snippet 1.1. AuthenticationProcess.bpel

<?xml version="1.0" encoding="UTF-8"?>
<process
    name="AuthenticationProcess"
    targetNamespace="http://enterprise.netbeans.org/bpel/Amset2Authentication/AuthenticationProcess"
    xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:sxt="http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/Trace" 
    xmlns:sxed="http://www.sun.com/wsbpel/2.0/process/executable/SUNExtension/Editor"
    xmlns:tns="http://enterprise.netbeans.org/bpel/Amset2Authentication/AuthenticationProcess" xmlns:ns0="http://j2ee.netbeans.org/wsdl/Amset2Authentication/InitAuthenticationWS" xmlns:ns1="http://enterprise.netbeans.org/bpel/AuthenticationServiceWrapper" xmlns:ns2="http://www.alfresco.org/ws/service/authentication/1.0">
    <import namespace="http://j2ee.netbeans.org/wsdl/Amset2Authentication/InitAuthenticationWS" location="InitAuthenticationWS.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"/>
    <import namespace="http://enterprise.netbeans.org/bpel/AuthenticationServiceWrapper" location="AuthenticationServiceWrapper.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"/>
    <import namespace="http://www.alfresco.org/ws/service/authentication/1.0" location="AuthenticationService.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"/>
    <partnerLinks>
        <!--[B]--><partnerLink name="AuthenticationServicePL" partnerLinkType="ns1:AuthenticationServiceSoapPortLinkType" partnerRole="AuthenticationServiceSoapPortRole"/>
        <!--[A]--><partnerLink name="InitAuthenticationPL" partnerLinkType="ns0:InitAuthenticationWS" myRole="InitAuthenticationWSPortTypeRole"/>
    </partnerLinks>
    <variables>
        <variable name="EndSessionOut" messageType="ns2:endSessionResponse"/>
        <variable name="EndSessionIn" messageType="ns2:endSessionRequest"/>
        <variable name="InitAuthenticationWSOperationOut" messageType="ns0:InitAuthenticationWSOperationResponse"/>
        <variable name="StartSessionOut" xmlns:auth="http://www.alfresco.org/ws/service/authentication/1.0" messageType="auth:startSessionResponse"/>
        <variable name="StartSessionIn" xmlns:auth="http://www.alfresco.org/ws/service/authentication/1.0" messageType="auth:startSessionRequest"/>
        <variable name="InitAuthenticationWSOperationIn" messageType="ns0:InitAuthenticationWSOperationRequest"/>
    </variables>
    <sequence>
        <!--[1]--><receive name="Receive1" createInstance="yes" partnerLink="InitAuthenticationPL" operation="InitAuthenticationWSOperation" portType="ns0:InitAuthenticationWSPortType" variable="InitAuthenticationWSOperationIn"/>
        <!--[2]--><assign name="Assign1">
            <copy>
                <from variable="InitAuthenticationWSOperationIn" part="username"/>
                <to>$StartSessionIn.parameters/ns2:username</to>
            </copy>
            <copy>
                <from variable="InitAuthenticationWSOperationIn" part="password"/>
                <to>$StartSessionIn.parameters/ns2:password</to>
            </copy>
        </assign>
        <!--[3]--><invoke name="Invoke1" partnerLink="AuthenticationServicePL" operation="startSession" xmlns:auth="http://www.alfresco.org/ws/service/authentication/1.0" portType="auth:AuthenticationServiceSoapPort" inputVariable="StartSessionIn" outputVariable="StartSessionOut"/>
        <!--[4]--><assign name="Assign2">
            <copy>
                <from>$StartSessionOut.parameters/ns2:startSessionReturn/ns2:ticket</from>
                <to>$EndSessionIn.parameters/ns2:ticket</to>
            </copy>
        </assign>
        <!--[5]--><invoke name="Invoke2" partnerLink="AuthenticationServicePL" operation="endSession" portType="ns2:AuthenticationServiceSoapPort" inputVariable="EndSessionIn" outputVariable="EndSessionOut"/>
        <!--[6]--><assign name="Assign3">
            <copy>
                <from>$StartSessionOut.parameters/ns2:startSessionReturn/ns2:username</from>
                <to variable="InitAuthenticationWSOperationOut" part="username"/>
            </copy>
            <copy>
                <from>$StartSessionOut.parameters/ns2:startSessionReturn/ns2:ticket</from>
                <to variable="InitAuthenticationWSOperationOut" part="ticket"/>
            </copy>
            <copy>
                <from>$StartSessionOut.parameters/ns2:startSessionReturn/ns2:sessionid</from>
                <to variable="InitAuthenticationWSOperationOut" part="sessionId"/>
            </copy>
            
        </assign>
        <!--[7]--><reply name="Reply1" partnerLink="InitAuthenticationPL" operation="InitAuthenticationWSOperation" portType="ns0:InitAuthenticationWSPortType" variable="InitAuthenticationWSOperationOut"/>
    </sequence>
</process>

Input/Output#

Code snippet 1.2. InitAuthenticationWS SOAP Request

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <ns1:startSession
            xmlns:msgns="http://www.alfresco.org/ws/service/authentication/1.0" xmlns:ns1="http://www.alfresco.org/ws/service/authentication/1.0">
            <ns1:username>admin</ns1:username>
            <ns1:password>adminpassword</ns1:password>
        </ns1:startSession>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Code snippet 1.3. InitAuthenticationWS SOAP Response

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <startSessionResponse xmlns="http://www.alfresco.org/ws/service/authentication/1.0">
            <startSessionReturn>
                <username>admin</username>
                <ticket>TICKET_39410d7b4d91e85a78f896822f1ff9edd07d10d2</ticket>
                <sessionid>256C5F7B29C64291B5962519D122C485</sessionid>
            </startSessionReturn>
        </startSessionResponse>
    </soapenv:Body>
</soapenv:Envelope>

Faults#

If an invalid set of credentials is received by Alfresco, then an exception is thrown in the Acegi security system and the following SOAP fault message is returned.

Code snippet 1.4. AuthenticationFault SOAP response

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:Server.generalException</faultcode>
            <faultstring/>
            <detail>
                <ns1:AuthenticationFault xmlns:ns1="http://www.alfresco.org/ws/service/authentication/1.0">
                    <ns1:errorCode>100</ns1:errorCode>
                    <ns1:message>net.sf.acegisecurity.BadCredentialsException: Bad credentials presented
net.sf.acegisecurity.BadCredentialsException: Bad credentials presented
	at net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider.getUserFromBackend(DaoAuthenticationProvider.java:393)
	at net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider.authenticate(DaoAuthenticationProvider.java:225)
	at net.sf.acegisecurity.providers.ProviderManager.doAuthentication(ProviderManager.java:159)
	at net.sf.acegisecurity.AbstractAuthenticationManager.authenticate(AbstractAuthenticationManager.java:49)
	at org.alfresco.repo.security.authentication.AuthenticationComponentImpl.authenticateImpl(AuthenticationComponentImpl.java:74)
	at org.alfresco.repo.security.authentication.AbstractAuthenticationComponent.authenticate(AbstractAuthenticationComponent.java:130)
	at org.alfresco.repo.security.authentication.AuthenticationServiceImpl.authenticate(AuthenticationServiceImpl.java:118)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:296)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:177)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
	at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:80)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
	at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:49)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
	at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:275)
	at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:69)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
	at $Proxy24.authenticate(Unknown Source)
	at org.alfresco.repo.webservice.authentication.AuthenticationWebService.startSession(AuthenticationWebService.java:83)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCProvider.java:397)
	at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:186)
	at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:323)
	at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
	at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
	at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
	at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:454)
	at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281)
	at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)
</ns1:message>
                </ns1:AuthenticationFault>
                <ns2:exceptionName xmlns:ns2="http://xml.apache.org/axis/">org.alfresco.repo.webservice.authentication.AuthenticationFault</ns2:exceptionName>
                <ns3:stackTrace xmlns:ns3="http://xml.apache.org/axis/">
	at org.alfresco.repo.webservice.authentication.AuthenticationWebService.startSession(AuthenticationWebService.java:96)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCProvider.java:397)
	at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:186)
	at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:323)
	at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
	at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
	at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
	at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:454)
	at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281)
	at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
	at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Thread.java:619)
</ns3:stackTrace>
                <ns4:hostname xmlns:ns4="http://xml.apache.org/axis/">myhost.leeds.ac.uk</ns4:hostname>
            </detail>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>


Similar to exception handling in Java, it is possible to catch faults in the BPEL process and initiate appropriate faulthandler processes. As a simple example, if we add the following variable to the process above


Code snippet 1.5.

<variable name="InvalidCredentialsFaultVar" messageType="ns0:InitAuthenticationFault"/>


and add the following faulthandlers element after the variables block


Code snippet 1.6.

<faultHandlers>
        <catchAll>
            <sequence name="Sequence1">
                <assign name="Assign4">
                    <copy>
                        <from>'Authentication Fault of Indeterminate Nature'</from>
                        <to variable="InvalidCredentialsFaultVar" part="faultMessage"/>
                    </copy>
                </assign>
                <reply name="Reply2" partnerLink="InitAuthenticationPL" operation="InitAuthenticationWSOperation" portType="ns0:InitAuthenticationWSPortType" faultName="ns0:invalidCredentialsFault" variable="InvalidCredentialsFaultVar"/>
            </sequence>
        </catchAll>
    </faultHandlers>


then we get the following process diagram


Figure 1.2 AuthenticationProcess plus catchall fault handler.



Now in response to receiving an invalid set of credentials the SOAP message received by the client is simply


Code snippet 1.7.

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/soap/envelope/ http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode xmlns="">SOAP-ENV:Client</faultcode>
      <faultstring xmlns="">invalidCredentialsFault</faultstring>
      <detail xmlns="">
        <faultMessage>Authentication Fault of Indeterminate Nature</faultMessage>
      </detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


and the nasty stack trace from the native Alfresco exception is no longer visible. The fault message code in the InitAuthenticationWS wsdl is


Code snippet 1.8.

<wsdl>
...
...
<message name="InitAuthenticationFault">
        <part name="faultMessage" type="xsd:string" />
    </message>
    <portType name="InitAuthenticationWSPortType">
        <operation name="InitAuthenticationWSOperation">
            <input name="input1" message="tns:InitAuthenticationWSOperationRequest"/>
            <output name="output1" message="tns:InitAuthenticationWSOperationResponse"/>
            <fault name="invalidCredentialsFault" message="tns:InitAuthenticationFault"/>
        </operation>
    </portType>
    <binding name="InitAuthenticationWSBinding" type="tns:InitAuthenticationWSPortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="InitAuthenticationWSOperation">
            <soap:operation/>
            <input name="input1">
                <soap:body use="literal" namespace="http://j2ee.netbeans.org/wsdl/Amset2Authentication/InitAuthenticationWS"/>
            </input>
            <output name="output1">
                <soap:body use="literal" namespace="http://j2ee.netbeans.org/wsdl/Amset2Authentication/InitAuthenticationWS"/>
            </output>
            <fault name="invalidCredentialsFault">
                <soap:fault name="invalidCredentialsFault" namespace="http://j2ee.netbeans.org/wsdl/Amset2Authentication/InitAuthenticationWS" use="literal"/>
            </fault>
        </operation>
    </binding>
...
...
</wsdl>

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
png
amset1authenticationfaulthandl... 33.3 kB 1 18-May-2009 19:49 clayton
png
amset1authenticationprocess2.p... 56.3 kB 1 13-May-2009 19:13 clayton
« This page (revision-) was last changed on 02-Sep-2009 15:02 by clayton