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
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 |