May 21, 2013

Logging in Apache CXF STS enhanced

This extension will be available in CXF release 2.7.6 which is not yet available. But you can run tests with the SNAPSHOT build till this version is released. Please provide feedback to the CXF mailing list.

Different logging frameworks (SLF4J, Log4J, Logback, JUL) can be used to log events for Apache CXF STS. The configuration allows to define which logger should log messages till to which log level. That works fine to drill down generic issues but it doesn't help too much to know whether a certain user could successfully log in or had any specific issues. Further, the WS-Trust interface is very generic. Therefore, the same user can request tokens but for different applications using different credential types. If a log in error occurs some context information is required to easily drill down user specific issues.

Based on the experience of a customer deployment, the following information is helpful to figure out how often a user requested a token and under which circumstances:

  • AppliesTo
    For which application did the user request a token
  • Source IP
    From which machine did the application request a token for a user
  • Claims
    Which claims did the user request for an application
  • Security Header
    How did the user try to log in (Username/password, Kerberos, X509, ...)
  • Realm
    For which security domain did the user request a token
  • etc.
All this information are available within the core classes of the STS and thus not customizable without patching these classes. The next release of CXF will provide a customizable logging/auditing functionality to fulfill various requirements.

Spring Eventing

The Spring framework provides an eventing mechanism which is designed for simple communication between Spring beans. Instead of introducing a new eventing mechanism to push data to a class which processes the data and writes it to a log file the new feature leverages the usage of the Spring framework in the CXF STS. How Spring eventing works is described on the following blog. If you don't want to delay STS related processing you can publish the events asynchronously which is described here.

CXF STS custom Application Events

Depending on the STS operation called, a different object with context information is created in the CXF STS. The following table summarizes the defined bindings in the WS-Trust specification, the CXF related context object as well a link with more information about this binding:

BindingContext objcectSpring EventDocumentation
IssueTokenProviderParametersSTSIssueSuccessEvent
STSIssueFailureEvent
blog
ValidateTokenValidatorParametersSTSValidateSuccessEvent
STSValidateFailureEvent
blog
CancelTokenCancellerParametersSTSCancelSuccessEvent
STSCancelFailureEvent
blog
RenewTokenRenewerParametersSTSRenewSuccessEvent
STSRenewFailureEvent
blog

The different binding implementations support the interface ApplicationEventPublisherAware thus they can publish events about a successful or failed request. You have to provide an implementation of ApplicationListener to listen to Spring Application Events. Due to the usage of generics you can specify which events you want to listen to. All the above STS specific events inherit the abstract class AbstractSTSEvent. If you want to listen to all STS events then you must provide an implementation like this:

public class AllSTSEventsListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(AbstractSTSEvent event) {
        // do whatever you want here
    }
}
If you want to listen to all successful issue events you must use the generic STSIssueSuccessEvent. The STS provides the LoggerListener which listens to all STS events and uses the CXF Logging API to write the log message. All you have to do is configure the following bean in the STS application context configuration (ex. cxf-transport.xml):
<bean id="loggerListener" class="org.apache.cxf.sts.event.LoggerListener" />

If you want to configure another Application listeners, just add a bean configuration and you're done.

The LoggerListener is able to log the following context information:

  • TIME
    Creation time of the event
  • OPERATION
    STS binding/operation
  • WS_SEC_PRINCIPAL
    Principal in WS-Security token
  • STATUS
    Successful/failed request
  • DURATION
    Processing time
  • TOKENTYPE
    Token type requested (SAML 1.1, SAML 2.0, etc)
  • REALM
    Security domain
  • APPLIESTO
    Application for which token is requested
  • CLAIMS
    Claims requested
  • ACTAS_PRINCIPAL
    Principal of ActAs token
  • ONBEHALFOF_PRINCIPAL
    Principal of On-Behalf-Of token
  • VALIDATE_PRINCIPAL
    Principal of Validate token
  • CANCEL_PRINCIPAL
    Principal of Cancel token
  • RENEW_PRINCIPAL
    Principal of Renew token
  • REMOTE_HOST
    Hostname/IP which requested the token
  • REMOTE_PORT
    Source Port which requested the token
  • URL
    STS URL used to request token
The LoggerListener provides the following properties to customize its behaviour:

NameTypeMandatoryDefaultDescription
logFieldnameBooleanNoNoShould the fieldname be logged, ex. OPERATION=issue
dateFormatStringNogetDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)Format of the date
logLevelStringNoFINEWhich log level should be used?
logStacktraceBooleanNoNoIn case of an error, shall the stacktrace be logged?
fieldOrderList<String>NoTIME
STATUS
DURATION
REMOTE_HOST
REMOTE_PORT
OPERATION
URL
REALM
WS_SEC_PRINCIPAL
ONBEHALFOF_PRINCIPAL
ACTAS_PRINCIPAL
VALIDATE_PRINCIPAL
CANCEL_PRINCIPAL
RENEW_PRINCIPAL
TOKENTYPE
APPLIESTO
CLAIMS
EXCEPTION
Order of context fields to be logged

If you want that all LoggerListener related log messages are written into a different file (ex. audit.log) I highly recommend to not use Java Util Logging as it's not so easy to configure a dedicated handler/appender for one logger.

  1. Configure Log4J as the logging framework in CXF (see here)
  2. Add the log4j dependency to your POM
  3. Configure the logger and appender
    log4j.rootLogger=INFO, CONSOLE, LOGFILE
    log4j.logger.org.apache.cxf.sts.event.LoggerListener=DEBUG, AUDIT
    
    # CONSOLE is set to be a ConsoleAppender using a PatternLayout.
    log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
    log4j.appender.CONSOLE.Threshold=INFO
    log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
    log4j.appender.CONSOLE.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n
    
    # AUDIT is set to be a File appender using a PatternLayout.
    log4j.appender.AUDIT=org.apache.log4j.FileAppender
    log4j.appender.AUDIT.File=${catalina.base}/logs/audit.log
    log4j.appender.AUDIT.Append=true
    log4j.appender.AUDIT.Threshold=DEBUG
    log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout
    log4j.appender.AUDIT.layout.ConversionPattern=%m%n
    
The audit log file looks like this if configured as above:
5/10/13 8:59:59 AM;SUCCESS;2839ms;127.0.0.1;57378;Issue;https://localhost:9443/fediz-idp-sts/STSService;null;alice;null;null;http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0;https://localhost:8081/doubleit/services/doubleittransportsaml1claims;null;null;

Enjoy.

May 14, 2013

LDAP support enhanced for CXF STS 2.7.5

I described in a previous blog how to configure the CXF STS for an LDAP directory for authentication and to retrieve user claims (attributes). The new release 2.7.5 of CXF provides extended support for roles managed in a LDAP directory. In previous versions, the LdapClaimsHandler added groups as roles if the groups were assigned to a multi-value attribute of the user. The new release provides an LdapGroupClaimsHandler which supports the case where an attribute of the groups lists the users who belong to this group. Further, it introduces the semantic of an application role. A user might have the role "User" for application X and role "Manager" and "User" for application Y.

The STS provides the semantic of an application with the AppliesTo parameter which is a URI. If you request a SAML token which includes the roles for a specific application (ex. MyApp), you get User and Manager back. A mapping is required in the STS to map the AppliesTo URI (URL or URN) to a String value like MyApp.

The sub-project Fediz provides in 1.1 (not released yet) a Maven profile to build the STS with an LDAP backend (instead of managing users/claims in a file). You can have a look at the ldap.xmlhere. The following configuration configures the LdapClaimsHandler and LdapGroupClaimsHandler. There is nothing special for the LdapClaimsHandler. The LdapGroupClaimsHandler also uses the Spring LdapContextSource and LdapTemplate.

    <util:list id="claimHandlerList">
        <ref bean="userClaimsHandler" />
        <ref bean="groupClaimsHandler" />
    </util:list>

    <bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="url" value="ldap://localhost:389/" />
        <property name="userDn" value="uid=admin,ou=system" />
        <property name="password" value="secret" />
    </bean>

    <bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
        <constructor-arg ref="contextSource" />
    </bean>

    <util:map id="claimsToLdapAttributeMapping">
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
            value="givenName" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
            value="sn" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
            value="mail" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country"
            value="c" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode"
            value="postalCode" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress"
            value="postalAddress" />                        
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality"
            value="town" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince"
            value="st" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender"
            value="gender" />
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth"
            value="dateofbirth" />                                                
        <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"
            value="member" />
    </util:map>

    <bean id="userClaimsHandler" class="org.apache.cxf.sts.claims.LdapClaimsHandler">
        <property name="ldapTemplate" ref="ldapTemplate" />
        <property name="claimsLdapAttributeMapping" ref="claimsToLdapAttributeMapping" />
        <property name="userBaseDN" value="ou=users,dc=fediz,dc=org" />
        <property name="userNameAttribute" value="uid" />
    </bean>
    
    <util:map id="appliesToScopeMapping">
        <entry key="urn:org:apache:cxf:fediz:fedizhelloworld"
            value="Example" />
    </util:map>
    
    <bean id="groupClaimsHandler" class="org.apache.cxf.sts.claims.LdapGroupClaimsHandler">
        <property name="ldapTemplate" ref="ldapTemplate" />
        <property name="userBaseDN" value="ou=users,dc=fediz,dc=org" />
        <property name="userNameAttribute" value="uid" />
        <property name="groupBaseDN" value="ou=groups,dc=fediz,dc=org" />
        <property name="appliesToScopeMapping" ref="appliesToScopeMapping" />
    </bean>
    
    <jaxws:endpoint id="transportSTS1" implementor="#transportSTSProviderBean"
        address="/STSService" wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
        xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        serviceName="ns1:SecurityTokenService" endpointName="ns1:TransportUT_Port">
        <jaxws:properties>
            <entry key="ws-security.ut.validator">
                <bean class="org.apache.ws.security.validate.JAASUsernameTokenValidator">
                    <property name="contextName" value="LDAP" />
                </bean>
            </entry>
        </jaxws:properties>
    </jaxws:endpoint>
I've highlighted the important beans to support the mapping of groups to (application) roles. The bean LdapGroupClaimsHandler has got the following attributes:

NameMandatoryDefaultDescription
ldapTemplateYesN.A.The Spring LDAP template
groupBaseDNYesN.A.The base group context where the search starts
groupObjectClassNogroupOfNamesObject class for groups. Used for search filter.
groupMemeberAttributeNomemberThe group attribute where the list of users are stored
groupURINohttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/roleThe SAML attribute name where the roles should be stored
groupNameGlobalFilterNoROLEDefault uses the CN of the group as role name
groupNameScopedFilterNoSCOPE_ROLEDefault cuts the SCOPE and the underscore of the CN of the group
appliesToScopeMappingNoN.A.The mapping is required if application specific roles must be supported
userNameAttributeNocnUser id attribute. Only required if LDAP is not used for authentication and thus the DN of the user must be resolved first. Used for search filter.
userObjectClassNopersonObject class for users. Only required if LDAP is not used for authentication and thus the DN of the user must be resolved first. Used for search filter.

The bean appliesToScopeMapping defines the mapping of the URI in the AppliesTo variable to a Name as URI's are not valid within a CN of an LDAP group.

One example for the usage of groupNameScopedFilter. One more example. Let's assume you use the same LDAP directory for the application environemnt development and pre-production and defines the following naming convention for application roles:
DEV_<Application>_<ROLE>_Group and UAT_<Application>_<ROLE>_Group The groupNameScopedFilter will look like this DEV_SCOPE_ROLE_Group (assumption: Different STS instances are deployed for development and pre-production).

The following table lists a few group examples and how the role value will look like in the SAML attribute. The assumption is that the AppliesTo element is urn:org:apache:cxf:fediz:fedizhelloworld which maps to the scope Example (see configuration example above) and the groupNameScopedFilter is configured like DEV_SCOPE_ROLE_Group:

Group CNRole name
DEV_Example_User_GroupUser
DEV_Example_Admin_GroupAdmin
DEV_Example2_User_Groupignored
UAT_Example_User_Groupignored
INFR_Citrix_Accessignored

Last but not least I'd like to comment the default value of userNameAttribute which is CN. As per recommendation (5.4) the CN is typically the person's fullname and therefore doesn't fit for the user id (login name). Due to the reason that the LdapClaimsHandler had the cn as default value I wanted to keep that in sync and change it in the next non-patch release of CXF.

If you face issues or like more functionality send a message to the CXF mailing list or open a JIRA issue.

April 22, 2013

Full Spring Security Support in Apache CXF Fediz

Full Spring Security Support in Apache CXF Fediz

New features are going to be added in the next version 1.1 of Fediz. I described here how to configure the new Fediz plugin for Spring Security with Container Managed Security (Pre-Authentication in Spring Security terms). The current snapshot version of Fediz 1.1 provides also full/native Spring Security support which means the Servlet Container runs unauthenticated (no security constraints defined in web.xml) and Spring Security enforces authentication.

You can either download the sources here:

git clone git://git.apache.org/cxf-fediz.git

or

svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk

or download it from the snapshot maven repository.

A new example springWebapp has been added to the distribution to show this.

As in the Pre-Authentication case, the application can get access to the Spring Security Context like this: SecurityContextHolder.getContext().getAuthentication(); The Authentication object is of instance FederationAuthenticationToken provides the following methods.

>
MethodClassDescription
getCredentialsElementIssues Security Token (ex. SAML Assertion)
getDetailsWebAuthenticationDetailsAuthentication details like IP, Session ID
getNameStringAuthenticated user name
getAuthoritiesCollection<? extends GrantedAuthority>List of roles
getUserDetailsFederationUserExtends the standard Spring User class with method getClaims()

You can get more information from the Fediz Wiki how to configure Spring Security or have a look at the example here. The example shows how to configure Fediz for Spring Security and how to use the Spring Security API in your application code. Please post feedback and ideas to the CXF mailing list or the JIRA task FEDIZ-39.

Apache CXF Fediz is a subproject of Apache CXF. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is WS-Federation Passive Requestor Profile.

Thank you for all support and feedback!

March 4, 2013

SSO and Fine Grained Authorization in the Cloud

In February 2013, I was at ApacheCon NA 2013 in Portland, Oregon, US where I learned a lot about several Apache projects.

My presentation was about SSO and Fine Grained Authorization in the Cloud. I gave an introduction about application security 10-15 years ago and how to address challanges with Cloud deployment using Apache CXF Fediz.

Here are the slides from my talk:

February 13, 2013

Spring Security support added in Apache CXF Fediz

Initial support for Spring Security in Apache CXF Fediz added

New features are going to be added in the next version 1.1. The next feature ready for testing is the support for Spring Security for version 3.1

You can either download the sources here:

git clone git://git.apache.org/cxf-fediz.git

or

svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk

or download it from the snapshot maven repository.

The Fediz Spring Plugin supports integration with the Spring Pre-Authentication scenario as described here.

A new example springPreauthWebapp has been added to the distribution to show this.

I'd like to highlight two things.

1) You can get access to the Spring Security Context like this: SecurityContextHolder.getContext().getAuthentication(); The Authentication interfaces provides the following methods.

>
MethodClassDescription
getCredentialsElementIssues Security Token (ex. SAML Assertion)
getDetailsPreAuthenticatedGrantedAuthoritiesWebAuthenticationDetailsAuthentication details like IP, Session ID
getNameStringAuthenticated user name
getAuthoritiesCollection<? extends GrantedAuthority>List of roles
getPrincipalFederationUserExtends the standard Spring User class with method getClaims()

Here is an example where the information of the Authentication object is logged:

getCredentials: [saml2:Assertion: null] getDetails: org.springframework.security.web.authentication.preauth.PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails@1c07a: RemoteIpAddress: 127.0.0.1; SessionId: go3xw6sxzqr5w02gn85elfgv; [ROLE_USER] getName: alice getAuthorities: [ROLE_USER] getPrincipal: org.apache.cxf.fediz.spring.FederationUser@5899680: Username: alice; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_USER

2) You can define rules who can access which resource as illustrated in the following snippet of applicationContext-security.xml of the new example springPreauthWebapp Please post feedback and ideas to the CXF mailing list or the JIRA task FEDIZ-38 and FEDIZ-39.

Apache CXF Fediz is a subproject of Apache CXF. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is WS-Federation Passive Requestor Profile.

Thank you for all support and feedback!

November 26, 2012

Jetty support added in Apache CXF Fediz

Initial support for Jetty in Apache CXF Fediz added

Apache CXF Fediz is a subproject of Apache CXF. Fediz helps you to secure your web applications and delegate security enforcement to the underlying application server. With Fediz, authentication is externalized from your web application to an identity provider installed as a dedicated server component. The supported standard is WS-Federation Passive Requestor Profile.

Fediz 1.0.2 supports the following features:

  • WS-Federation 1.0/1.1/1.2
  • SAML 1.1/2.0 Tokens
  • Custom token support
  • Publish WS-Federation Metadata document
  • Role information encoded as AttributeStatement in SAML 1.1/2.0 tokens
  • Claims information provided by FederationPrincipal interface

New features are going to be added in the next version 1.1. The first feature ready for testing is the support for the Open Source Servlet Container Jetty for version 7 and 8.

You can either download the sources here:

git clone git://git.apache.org/cxf-fediz.git

or

svn co https://svn.apache.org/repos/asf/cxf/fediz/trunk

or download it from the snapshot maven repository.

As Jetty can easily be embedded in your application you might be interested to look at the Unit test for the Jetty module how to configure the FederationAuthenticator. If you download the Jetty distribution the configuration for Fediz is described here. Please post feedback and ideas to the CXF mailing list or the Jira task FEDIZ-5.

Thank you for all support and feedback!

July 31, 2012

Add End-To-End monitoring to Your CXF application with Open Source

This is the second blog I mentioned here.

I'd like to show how to add end-to-end monitoring to your CXF based applications. End-to-end monitoring means that you can follow the message flow which has been triggered by a user across several web services nodes (consumer/provider). Context information of a message and its content are pushed by every web service node to a central server component. The communication style is asynchronous to not delay message processing.

To show how this can be achieved I'll also use the example wsclientWebapp of the Apache CXF Fediz project which I already used to illustrate how to add load balancing and failover. Further information is available here.

This example already supports Web SSO (IDP), WS-Security and STS. The architecture is described in a previous blog.

A web appliation is federation enabled with Fediz to support SSO. As part of the login of the browser user, a SAML token is issued which contains the claims information which are relevant to the web application. The web application calls a web service on behalf of the logged in user. This is accomplished by the CXF STS which is shipped as part of the Fediz in the IDP/STS component. The Web Service Consumer (Web Application) requests a new token based on the WS-SecurityPolicy of the Web Service Provider on behalfof of the security token issued as part of the Web Login. In this example, the security tokens are SAML tokens.

More information on how to build, deploy and test the demo are described in the README.

This example has the following gaps to be deployed in a distributed environment:

  • URL's of the web service provider is configured on the service consumer side which is difficult to manage across the environments and for all web service consumers
  • If an error occurs you have to analyze log files of all involved nodes in the message flow to drill down the root cause of the issue. Usually, the log files of all involved applications are distributed in the network. It's difficult to correlate the messages in the different log files.
These issues might be manageable within the scope of a project but not on the enterprise level as your application might consume several services which are used by other applications as well. As mentioned at the beginning, the first gap is addressed in the previous blog. This blog will address how to add end-to-end monitoring.

Talend built Apache licensed open source components to add load balancing, failover and end-to-end monitoring to your CXF/Camel based applications. This blog shows you how easily you can integrate this component into your application.

Update your CXF application

Talend built a SAM (Service Activity Monitoring) server component where service participants (consumer/provider) can send information about incoming and outgoing messages. The SAM server is Apache licensed. Besides the server component, the SAM agent is deployed as part of the CXF application which hooks into the interceptor chain to collect all required information about the message and pushes it to the SAM server asynchronously.

What do you have to do in your application?

A) Web Service Provider

Make the following changes in the maven project wsclientWebapp/webservice/service

1) add POM dependency for the Talend SAM agent library

This library hooks into the CXF interceptor chain to send service activity information to the SAM server.

  <dependency>
    <groupId>org.talend.esb</groupId>
    <artifactId>sam-agent</artifactId>
    <version>5.1.1</version>
  </dependency>
2) add a file agent.properties to your maven project src/main/resources

This file contains information where the SAM agent is running and what kind of information should be sent.

collector.scheduler.interval=500
collector.maxEventsPerCall=10
collector.lifecycleEvent=false

log.messageContent=true
log.maxContentLength=-1
log.enforceMessageIDTransfer=false

service.url=http://localhost:8040/services/MonitoringServiceSOAP
service.retry.number=3
service.retry.delay=5000
3) Update Spring configuration file applicationContext.xml

The highlighted lines must be added to the example application.

...
   <import resource="classpath:META-INF/cxf/cxf.xml" />
   <import resource="classpath:META-INF/tesb/locator/beans.xml" />
   <import resource="classpath:META-INF/tesb/agent-context.xml" /> 
...
   <!-- GreeterService -->
   <jaxws:endpoint id="GreeterService"
      implementor="org.apache.cxf.fediz.examples.service.GreeterImpl"
      wsdlLocation="WEB-INF/wsdl/hello_world.wsdl"
      serviceName="svc:GreeterService"
      xmlns:svc="http://apache.org/hello_world_soap_http"
      address="/GreeterService">

      <jaxws:properties>
         <entry key="ws-security.signature.properties" value="stsKeystore.properties" />
         <entry key="org.talend.tesb.endpoint.secured" value="true"/>
      </jaxws:properties>

      <!-- Talend feature -->
      <jaxws:features>
         <bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" />
         <ref bean="eventFeature"/>
      </jaxws:features>
   </jaxws:endpoint>
4) Run "mvn clean install"

Maven builds a new WAR package. This package is now able to send service activity information to the SAM server.

B) Web Service Consumer

Make the following changes in the maven project wsclientWebapp/webapp

1) add POM dependency for the Talend SAM agent library

This library hooks into the CXF interceptor chain to send service activity information to the SAM server.

  <dependency>
    <groupId>org.talend.esb</groupId>
    <artifactId>sam-agent</artifactId>
    <version>5.1.1</version>
  </dependency>
2) add a file agent.properties to your maven project src/main/resources

This file contains information where the SAM agent is running and what kind of information should be sent.

collector.scheduler.interval=500
collector.maxEventsPerCall=10
collector.lifecycleEvent=false

log.messageContent=true
log.maxContentLength=-1
log.enforceMessageIDTransfer=false

service.url=http://localhost:8040/services/MonitoringServiceSOAP
service.retry.number=3
service.retry.delay=5000
There are different options to configure what kind of information should be pushed to the SAM server. Please check the Talend_ESB_InfrastructureServices manual for all configuration options like:
  • Send message content
  • Configure maximum length of content to be sent
  • filters to find/replace in message content
  • add custom context information
  • ...
3) Update Spring configuration file applicationContext.xml

The highlighted lines must be added to the example application.

...
   <import resource="classpath:META-INF/cxf/cxf.xml" />
   <import resource="classpath:META-INF/tesb/locator/beans.xml" />
   <import resource="classpath:META-INF/tesb/agent-context.xml" /> 
...
  <jaxws:client id="HelloServiceClient" serviceName="svc:GreeterService"
    xmlns:svc="http://apache.org/hello_world_soap_http"
    serviceClass="org.apache.hello_world_soap_http.Greeter"
    address="locator://whatever"
    wsdlLocation="WEB-INF/wsdl/hello_world.wsdl">
    <jaxws:properties>
      <entry key="ws-security.sts.client">
        <bean class="org.apache.cxf.ws.security.trust.STSClient">
          <constructor-arg ref="cxf" />
          <property name="wsdlLocation" value="https://localhost:9443/fedizidpsts/STSServiceTransport?wsdl" />
          <property name="serviceName"
            value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService" />
          <property name="endpointName"
            value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}Transport_Port" />
          <property name="onBehalfOf" ref="delegationCallbackHandler" />
          <property name="enableAppliesTo" value="true" />
        </bean>
      </entry>
    <entry key="ws-security.cache.issued.token.in.endpoint" value="false" />
    </jaxws:properties>
    <jaxws:features>
      <bean class="org.talend.esb.servicelocator.cxf.LocatorFeature" />
      <ref bean="eventFeature"/>
    </jaxws:features>
  </jaxws:client>
4) Run "mvn clean install"

Maven builds a new WAR package. This package is now able to send service activity information to the SAM server.

Deploy SAM server

Last but not least, the Talend SAM server must be deployed and started which is shipped as part of the Talend ESB. Follow these steps to start the SAM server (if you have run already the demo for the Service Locator you only have to run tesb:start-all):
  1. Download the Talend ESB Standard Edition (SE) here. The Standard Edition has full functionality and is Apache licensed.
  2. Unzip the file
  3. Run <install-dir>/container/trun
  4. Execute the following command in the console

    tesb:start-all

  5. You can log the most recent logs with the command

    log:display

The SAM server (and Service Locator) are running now.

More information about the Talend ESB is available here:

Test the application

You can test the application as described in the README of the Fediz example wsclientWebapp.

Enter the URL https://localhost:8443/fedizhelloworld/secure/service.jsp and click on the button Call Service after login (User: alice, Password: ecila). This triggers a web service call.

You will also see that messages are sent to the SAM server from the service consumer and service provider:

...
Jul 5, 2012 11:21:09 PM org.talend.esb.sam.agent.collector.EventCollector sendEvents
INFO: Put events(2) to Monitoring Server.
...

You can use any DB Visualizer Tool to show the data of the messages exchanged in the web services network. In this example, the data is written to Apache Derby.

You find more information where this DB is located in Talend_ESB_InfrastructureServices in chapter 4.3.

This is not a very nice UI to see which messages are part of a flow triggered by a user. In my next blog I'll describe the Talend Administration Console (TAC) which allows to see the messages exchanged and the registered service in a graphical way.

This blog showed how easy it is to add end-to-end monitoring capabilities to your CXF application with open source components and without changing a single line of code.