> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication using SAML identity providers in ABBYY FlexiCapture 12

> Authenticate ABBYY FlexiCapture 12 users via a SAML identity provider: get SAML data, POST it Base64-encoded to the Application Server, and use the ticket.

## Overview of the authentication process

SAML authentication keeps identity data, such as a user name and password, away from the Application Server. Instead, the user authenticates on a third-party identity provider such as Google or Facebook. That trusted third party then passes proof of successful authentication to the Application Server.

The SAML authentication process on a user application consists of the following steps:

* Authenticate on the third-party identity provider
* Get the user's SAML authentication data from the third-party identity provider
* Send the SAML authentication data to the Application Server
* Receive an authenticated ticket from the Application Server

This ticket can then be used in requests to the Application Server.

<Info>
  The user account must exist in the FlexiCapture database, with all of the required permissions.
</Info>

## Implementation

### Get SAML data

SAML data from the third-party identity provider is formatted as follows (this example is from OneLogin):

```xml theme={null}
<?xml version="1.0" encoding="UTF-8" ?>
   <samlp:Response xmlns:saml = "urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:samlp = "urn:oasis:names:tc:SAML:2.0:protocol" ID = "R85bc5e644b6749bf20939c99cacf35945d74bf48" Version = "2.0"
   IssueInstant = "2016-09-15T09:56:20Z" Destination = "{recipient}" InResponseTo = "_1ba6250c-3c4e-49e1-9bff-fc82bc266b34">
      <saml:Issuer>https://app.onelogin.com/saml/metadata/585198</saml:Issuer>
      <samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status>
      <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
         xmlns:xs="https://www.w3.org/2001/XMLSchema"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfx5b0edaf1-7296-f635-b387-a964c92e4d5f" IssueInstant="2016-09-15T09:56:20Z">
         <saml:Issuer>https://app.onelogin.com/saml/metadata/585198</saml:Issuer>
         <ds:Signature xmlns:ds="https://www.w3.org/2000/09/xmldsig#">
            <ds:SignedInfo>
               <ds:CanonicalizationMethod Algorithm="https://www.w3.org/2001/10/xml-exc-c14n#"/>
               <ds:SignatureMethod Algorithm="https://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
               <ds:Reference URI="#pfx5b0edaf1-7296-f635-b387-a964c92e4d5f">
                  <ds:Transforms>
                     <ds:Transform Algorithm="https://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                     <ds:Transform Algorithm="https://www.w3.org/2001/10/xml-exc-c14n#"/>
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="https://www.w3.org/2000/09/xmldsig#sha1"/>
                  <ds:DigestValue>udRgHOqBktJRsEzF5xkmJMOuwIk=</ds:DigestValue>
               </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>LfHQBqg+S72CtSefOA8KMNxTUpOJcFCdemZ2BlCU/FR1n6pnLqZT6+m90729ciy7CNzT/w40GCcuVDggcgDKFqDb47Wzc6vs7ejC8W9OAdbJKXBK5jwYeYcJO4utN15k4e18Bv8zv96Bx/C8mBxcflSSP5C/tDAtbzvPBsyd25qADNTsKxwppZxAh4frdmSFQ4rYCOO1PnBFrS3zzguGXB9ZM0V9AAPYEJ5nU046NIVt3FTwZFoycZW2PxG+/o/JSXWS6loPnQZkWkTwrIuAcRh1dPlOSDvllGELD4Z7BN4wEVXOFBJtaU+ILlBgncNwQvFIGLF5a6YhG0hGYLaPsA==</ds:SignatureValue>
            <ds:KeyInfo>
               <ds:X509Data>
                  <ds:X509Certificate>MIIEDjCCAvagAwIBAgIUQWL60N8pdoL8VJeC0v2eJV6OL4AwDQYJKoZIhvcNAQEFBQAwVTELMAkGA1UEBhMCVVMxDjAMBgNVBAoMBUFCQllZMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgOTE1MTcwHhcNMTYwOTA4MDkyNzA3WhcNMjEwOTA5MDkyNzA3WjBVMQswCQYDVQQGEwJVUzEOMAwGA1UECgwFQUJCWVkxFTATBgNVBAsMDE9uZUxvZ2luIElkUDEfMB0GA1UEAwwWT25lTG9naW4gQWNjb3VudCA5MTUxNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3vEVaTlbLjzwJPDpGCKC4TnCbnYMsxwInvKABFF4S21PYHG6M47zkO1MylP89BUXySk8TdeHb1Sd3upSoqGaM3uGd+/kv7KW71QQQG9AtczWom8VfPxju9L9t1bSsMVYjXGROv40H1Q99dGsFraiSvKAKUj5ABY6WdVNaKAU50y7XzbnwCGm65ErLwH4hW+t0wJew/hOWSb9grtKkBWNJN3BUGBOVG9YJD5U4OYGJJaeha/dvh+LpaKG2wT2EZUo/o6789bovh4VaTRqeuVruIyafxzljpOuyHSHu0JarsFqYR45NoMqMEJIbYcA62IeenAANpqwAWIb8+LPGr7YcCAwEAAaOB1TCB0jAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBS+6YWUYqLJeYXS8djijIaLxZlL+TCBkgYDVR0jBIGKMIGHgBS+6YWUYqLJeYXS8djijIaLxZlL+aFZpFcwVTELMAkGA1UEBhMCVVMxDjAMBgNVBAoMBUFCQllZMRUwEwYDVQQLDAxPbmVMb2dpbiBJZFAxHzAdBgNVBAMMFk9uZUxvZ2luIEFjY291bnQgOTE1MTeCFEFi+tDfKXaC/FSXgtL9niVeji+AMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUFAAOCAQEAbSP3ubKUVG/Jg6jOGKQ46Rr6nSgP7Sf9zWF6a08eBHXbt3YalPR/ORp9aE+hL82S8QybNxM9fLUcEpRYzZRKysMr1rJ9slCulydCNNlopQN5j+Htfd1tbqINQNNgnnRJnwIHyitREufHQ3Zb9OWWktmyfKjHbtQe+lthCxaIfac6gcPqTIZKgLiTVdnkw/15LvBNkOnjdh6cK1cZF5MF6WdxozgQwvlVQlvh7Bm5UYZ9yQfvtUmOCq+o51cF/gm+VCKCdkeavXL9YZmh6Jk5AcVaF2od29b5rtJSlDbWUnVBFHppVJ2iaWXDHcU0Ms6+hp/LpQG18o4iO9oYw25fXA==</ds:X509Certificate>
               </ds:X509Data>
            </ds:KeyInfo>
         </ds:Signature>
         <saml:Subject>
            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">maksim_p@abbyy.com</saml:NameID>
            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
               <saml:SubjectConfirmationData NotOnOrAfter="2016-09-15T09:59:20Z" Recipient="{recipient}" InResponseTo="_1ba6250c-3c4e-49e1-9bff-fc82bc266b34"/>
            </saml:SubjectConfirmation>
         </saml:Subject>
         <saml:Conditions NotBefore="2016-09-15T09:53:20Z" NotOnOrAfter="2016-09-15T09:59:20Z">
            <saml:AudienceRestriction>
               <saml:Audience>{audience}</saml:Audience>
            </saml:AudienceRestriction>
         </saml:Conditions>
         <saml:AuthnStatement AuthnInstant="2016-09-15T09:56:19Z" SessionNotOnOrAfter="2016-09-16T09:56:20Z" SessionIndex="_e5832a70-5d47-0134-7b4f-026cc9f4032d">
            <saml:AuthnContext>
               <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
            </saml:AuthnContext>
         </saml:AuthnStatement>
      </saml:Assertion>
   </samlp:Response>
```

For details on how to get authentication data from a third-party identity provider, see the identity provider's documentation. For instance, OneLogin offers [ready-to-use toolkits](https://www.onelogin.com/resources/saml-toolkits) for enabling SAML authentication in several programming languages.

### Send SAML data to FlexiCapture 12 Application Server

Encode the SAML data in Base64 and send it to the Application Server by making a POST request to `https://<Application Server>/Flexicapture12/Server/Saml`. The name of the field containing the SAML data should be `SAMLResponse`.

```csharp theme={null}
public static async Task sendSamlToServer( string samlData )
{
    string serviceUrl = "https://<ApplicationServer>/Flexicapture12/Server/SAML";
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create( serviceUrl );
    request.Method = "POST";

    var fields = new Dictionary<string, string>();
    fields.Add( "SAMLResponse", Convert.ToBase64String( Encoding.UTF8.GetBytes( samlData ) ) );
    HttpClient client = new HttpClient();
    FormUrlEncodedContent content = new FormUrlEncodedContent( fields );
    HttpResponseMessage response = await client.PostAsync( serviceUrl, content );
    if( response.StatusCode == HttpStatusCode.OK ) {
        processServerResponse( response.Content.ToString() );
    } else {
        processServerError( response.StatusCode, response.Content.ToString() );
    }
}
```

If you are using a tenant, add the tenant's identifier to the server URL, for example, `https://<ApplicationServer>/Flexicapture12/Server/Saml?Tenant=MyTenantName`

For authentication to work, a user with a login matching the identifier in the SAML data must be registered on the Application Server. The value of the `/samlp:Response/saml:Assertion/saml:Subject/saml:NameID` field will be used as the login.

The Application Server returns a response like this:

```xml theme={null}
<authTicket>
<userName>maksim_p@abbyy.com</userName> 
       <ticket>82BD00C6601EB7F8EF4265450F934D4103C5CA2F010DE1C5FAB4CC830A82300C743D09E5477279733F283D0B6E1C93ACC30FE353D4D9396649965432AAA7994078C3CC63567A95A35E03DA6FDE020F57</ticket> 
</authTicket>
```

The value in the `<ticket>` tag is the authenticated FlexiCapture 12 ticket. You can use this ticket to make calls to all Application Server interfaces that require authentication. Requests to FlexiCapture web services must be made using FlexiCapture authentication (addresses starting with `https://<ApplicationServer>/flexicapture12/Server/FCAuth/` or `https://<ApplicationServer>/flexicapture12/Server/MobileApp/`).

<h3 id="use-the-authenticated-fc-12-ticket">
  Use the authenticated FlexiCapture 12 ticket
</h3>

You can pass the ticket to the server using a cookie file (the file must be named `FlexiCaptureTmpPrn`) or an `Authorization: Bearer` header. Example:

```http theme={null}
Authorization: Bearer 82BD00C6601EB7F8EF4265450F934D4103C5CA2F010DE1C5FAB4CC830A82300C743D09E5477279733F283D0B6E1C93ACC30FE353D4D9396649965432AAA7994078C3CC63567A95A35E03DA6FDE020F57
```

Use the header. Cookies are supported for compatibility with older solutions.

On success, the server's response carries an updated ticket value in two places. One is a cookie file with the same login, `FlexiCaptureTmpPrn`, and the other is the `AuthTicket` header.

Use the updated ticket for the next request, since tickets expire after a time.

### Set up a trusted certificate on the Application Server

The Application Server will check the data received from the identity provider. For the Application Server to trust this data, sign it with a custom certificate. The issuing authority must appear in the Application Server database of trusted authorities.

Import the certificate to the ABBYY FlexiCapture database. Now data will be checked using this certificate. For more information, see [Set up Single Sign-On](/flexi-capture/sso-settings).

If the check fails, the Application Server refers to the `AllowMixedModeCertificateValidation` parameter under `<appSettings>` in the `Web.config` file. When that parameter is `true`, the check uses the certificate in the **Trusted Root Certification Authorities** folder. That folder sits in the Local Computer certificate store on the computer running the Application Server.

If the database holds no certificates, the check falls back to the certificate in the **Trusted Root Certification Authorities** folder. The `AllowMixedModeCertificateValidation` parameter is then ignored.

A sample project and its accompanying materials are available as `SAML_Example.zip`.
