Skip to main content

Posts

Showing posts from 2018

Content Delivery Monitoring in AWS with CloudWatch

This post describes a way of monitoring a Tridion 9 combined Deployer by sending the health checks into a custom metric in CloudWatch in AWS. The same approach can also be used for other Content Delivery services. Once the metric is available in CloudWatch, we can create alarms in case the service errors out or becomes unresponsive. The overall architecture is as follows: Content Delivery service sends heartbeat (or exposes HTTP endpoint) for monitoring Monitoring Agent checks heartbeat (or HTTP health check) regularly and stores health state AWS lambda function: runs regularly reads the health state from Monitoring Agent pushes custom metrics into CloudWatch I am running the Deployer ( installation docs ) and Monitoring Agent ( installation docs ) on a t2.medium EC2 instance running CentOS on which I also installed the Systems Manager Agent (SSM Agent) ( installation docs ). In my case I have a combined Deployer that I want to monitor. This consists of an Endpoint and a

Create User from JavaScript Client Using CoreService

This post presents some sample code on how to create a Tridion user from JavaScript client using the CoreService. It is based on the setup presented in previous posts and it only makes use of JQuery library. The logic below is also assigning the newly created user to certain Tridion Groups identified either by TCMURI, Name or Description. This means the code will first call the CoreService to retrieve a list of groups, then identify those we need to assign the user to, then create the UserData object with all group memberships set, and then finally send the request to create the user to CoreService. The code below is to be inserted into the ServiceProxy class. The entry point is the createUser method, which takes as parameters the user account, user name, and an array of groups to assign the new user. It also takes a success and fail callback functions. The code makes use of a number of classes defined below, such as UserData , GroupMembershipData , LinkToGroupData , etc. The

JQuery JavaScript Client for CoreService

In my previous post, I presented a JavaScript CoreService client that was using the out-of-the-box Visual Studio project and a WCF generated JS proxies using the Microsoft AJAX framework. In this blog post, I write about a JQuery client for CoreService that is lighter and only depends on JQuery. I took my inspiration from Yoav's blog post  Creating a Webservice Proxy with jQuery The server part remains untouched. This means I can only focus on the JavaScript client. CoreService is secured with Basic or Federated authentication. I am focusing on Basic auth in this post, mainly because it is so simple to use from JS. The main entry point in the code is the ServiceProxy class. This is where we define the constructor and where we set the endpoint to use for CoreService and the username, password combination to use. The ServiceProxy makes use of the JQuery's $.ajax function, where it performs a POST to the CoreService endpoint, sets the payload to send, Authorization hea

JavaScript Client for CoreService

This blog post shows a way to connect to CoreService directly from a JavaScript client. The CoreService is a WCF web-service, which by default uses SOAP to communicate with its clients. However, it is quite simple to convert it into a REST service that accepts plain POST requests with parameters sent in the request body. To keep things simple, I secured the REST endpoint with Basic auth, and thus made use of the Basic Authenticator handler over an HTTPS connection. The Server The WCF framework allows us to easily expose any web-service as a REST service. For this, I had to modify the file [SDLWebHome]\webservices\Web.config , and add an endpoint behavior under node <system.serviceModel> / <behaviors> . The new behavior enables endpoint to be accessible as REST service: <endpointBehaviors> <behavior name= "MyJS" > <enableWebScript /> </behavior> </endpointBehaviors> Next, because we want to use

Workflow Listener SDL Web 8.5 with ADFS

Using the Workflow listener service with ADFS authentication is quite straight forward, if we use the Basic Authenticator. The service WFListener.asmx is not a WCF service, therefore we can't use federation security on it. Instead we need to use Basic authentication and handle the ADFS behind the scene. The Basic Authenticator module exposes a Basic authentication scheme, while communicating with the ADFS server in the background. Once a user is successfully authenticated, it creates a Thread and HttpContext security contexts, so that the following modules in the .NET request processing pipeline execute in the new security context. As such, our client can define a Basic auth security using HTTPS transport and it will be able to connect to the service. App.config The .NET Console application I use as test client uses generated service proxy classes. The configuration presented below defines the endpoint to connect to and a simple HTTPS Basic auth transport. <system.ser

TemplateBuilder and Assembly Upload Services with ADFS

Using either of the templating services (i.e. AssemblyTemplateUploadWebService.asmx and CompoundTemplateWebService.asmx ) with ADFS authentication is quite straight forward, if we use the Basic Authenticator . This one exposes a Basic authentication scheme, while communicating with the ADFS server in the background. Once a user is successfully authenticated, it creates a Thread and HttpContext security contexts, so that the following modules in the .NET request processing pipeline execute in the new security context. As such, our client can define a Basic auth security using HTTPS transport and it will be able to connect to the service. This is the same mechanism the Content Porter application is using (i.e. Basic auth). App.config The .NET Console application I use as test client uses generated service proxy classes. The configuration presented below defines the endpoint to connect to and a simple HTTPS Basic auth transport. <system.serviceModel> <bindings&g

Content Porter 8.5 with ADFS

Content Porter uses Basic auth to communicate with the ImportExport service. This means the federated security approach will not work. Luckily, we have the Basic Authenticator that exposes the ADFS authentication as a basicHttp endpoint. Using this endpoint, the authenticator creates a new security principal and sets it in the current Thread and HttpContext . As such, Content Porter works again out of the box: For the Basic Authenticator to intercept requests for the basicHttp endpoint, I defined a regular expression that is matched against the URL of the request: <add key="BasicAuthPath" value="(?i)/templating/.+\.asmx|/webservices/(core|importexport)service\d{4,6}\.svc/(streamdownload_basichttp|basichttp|script(?!/js))|/wflistener/wflistener\.asmx|/webdav|/monitoring/tridionmonitoringagent.asmx"/> The expression above matches all requests to: /templating/ folder, and files that end with .asmx extension. These are the services  Asse

ImportExport Service with ADFS

Using the ImportExport service with ADFS authentication is quite straight forward, if we use the Basic Authenticator. This one exposes a Basic authentication scheme, while communicating with the ADFS server in the background. Once a user is successfully authenticated, it creates a Thread and HttpContext security contexts, so that the following modules in the .NET request processing pipeline execute in the new security context. As such, our client can define a Basic auth security using HTTPS transport and it will be able to connect to the service. This is the same mechanism the Content Porter application is using (i.e. Basic auth). App.config The .NET Console application I use as test client uses generated service proxy classes. The configuration presented below defines the endpoint to connect to and a simple HTTPS Basic auth transport. <system.serviceModel> <bindings> <basicHttpBinding> <binding name= "basicHttp" > &l

A Validating Saml2SecurityTokenHandler

In a previous blog post, I talked about a SecurityTokenHandlers collection of different security tokens. This is a class from the .NET security framework and it allows a unified entry to different types of tokens. In this post, I explain the need for a validating Saml2SecurityTokenHandler . The code for my overloaded property is something like this: private SecurityTokenHandlerCollection securityTokenHandlers; private SecurityTokenHandlerCollection SecurityTokenHandlers { get { if (securityTokenHandlers == null ) { securityTokenHandlers = new SecurityTokenHandlerCollection( FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers); for ( int i = 0 ; i < securityTokenHandlers.Count; i++) { if (securityTokenHandlers[i] is Saml2SecurityTokenHandler) { securityTokenHandlers[i] = new ValidatingSaml2SecurityToke

AdfsClient Class

As mentioned in a previous blog post, this class takes care of the interaction with the ADFS server. Its main functionality is to request and decrypt SAML tokens from an ADFS server. The class makes use of the .NET security token API, which in order to be used, it has to be configured. The easiest is to configure it through XML, in one of the application's .config files: <system.identityModel.services> <federationConfiguration> <serviceCertificate> <certificateReference storeLocation= "LocalMachine" storeName= "My" x509FindType= "FindByThumbprint" findValue= "30 4e 10 91 73 fb 34 6a 90 19 f5 e7 d4 fa 2d 11 21 10 3e 3d" /> </serviceCertificate> </federationConfiguration> </system.identityModel.services> The configuration above allows us to use the predefined System.IdentityModel.Tokens.Saml2SecurityTokenHandler . I used this class to handle the reading (i

Basic Authenticator Web 8.5 with ADFS

This post presents a Basic Authenticator wrapper around ADFS security. This authenticator allows a client and web-service to use Basic authorization security, while the actual security authentication happens on an ADFS server. The Basic Authenticator is a .NET HTTP module, which creates a security context based on a user principal that it receives from ADFS. All subsequent request processing happens in the context of this 'impersonated' context. The request processing sequence is as follows: Client connects to web-service using Basic authorization (over HTTPS, so the  Authorization  request header is not transmitted in the open) Basic Authenticator HTTP module intercepts the request If  Authorization  header is in the request Extract and decode username/password from  Authorization header If username/password is valid in ADFS Create user principal Set security context Let request processing continue Else Send 401 WWW-Authenticate response header Stop reques

CoreService and ADFS with Issued Token

If in an earlier post CoreService with ADFS , I was talking about XML configuration of the .NET client application when connecting to a SDL Web 8.5 instance secured with ADFS, in this post I am showing another way of connecting to the CoreService, namely using a SAML token requested through code rather than configuration. The main steps in this approach are: client .NET Console application requests programmatically a SAML token from the ADFS server client creates connection using issued token The setup on the SDL Web server and the configurations of the CoreService web-service are identical to those presented in the earlier post, therefore I won't mention them again here. App.Config The client is a .NET Console application using an App.config which defines the following CoreService endpoint: <system.serviceModel> <bindings> <ws2007FederationHttpBinding> <binding name= "myCoreServiceBinding" maxReceivedMessageSize= &quo