# Single Sign On

Single sign-on is a useful feature that allows users to log in to multiple applications and websites with one set of credentials. In this guide, we will explore how to integrate this functionality into your application using the LicenseSpring SDK.

### Prerequisites

* Completed the [**Getting Started**](/sdks/tutorials/getting-started.md) and [**User Based Licensing**](/sdks/tutorials/licensing-scenarios/user-based-licensing.md) tutorials, specifically:
  * Initialized LicenseManager (or LicenseHandler) with your configuration using the appropriate settings.
  * Activated the user-based license of any type.

### SSO Configuration

To implement SSO activation, add a customer account code to the configuration. The account code can be found on your LicenseSpring account under Customer->Customer accounts:

![](https://lh6.googleusercontent.com/nTTJwTqv6tPMKaoSFpNEeILrhgKA07sDYNlvo1yU6nfBftCSohNzNky77nyKelaY4l4cTcC6Ep6nM0X5MVlBSPZ6bGFwH1hj85xfXEx6s9C7vZ5di3NCa1vcDjFWDFNSxgDeOLyT9FonhKW6m_14qA)

When you have this value, set it to the configuration:

{% tabs %}
{% tab title="C++" %}

```cpp
auto configuration = LicenseSpring::Configuration::Create( ApiKey, SharedKey, ProductCode, AppName, AppVersion );
configuration->setCustomerAccount("licensespring");
```

{% endtab %}

{% tab title="C#" %}

```csharp
var configuration = new Configuration( ApiKey, SharedKey, ProductCode, AppName, AppVersion );
configuration.CustomerAccount = "licensespring";
```

{% endtab %}

{% tab title="Swift" %}

```swift
configuration.customerAccountCode = "licensespring"
```

{% endtab %}
{% endtabs %}

This value also can be set during the activation process, so you can use multiple customer accounts without reconfiguring the LicenseManager.

### Authorization URL

You can choose the authorization method when getting the authorization URL. There are two methods:

* Token: Implicit grant which attaches user pool tokens (id\_token, access\_token, expires\_in, and token\_type) to the redirect\_uri once the user is verified.
* Code: Authorization code grant method where the code query param is attached to the redirect URL instead of id\_token. This code is sent in the request body when doing license activation.

If you do not want to expose user tokens or the redirect URI is too long for your use case, we recommend using the code instead of the token. By default, the SDK returns the URL with the authorization code. To use the authorization token, pass the additional parameter to the getSSOUrl method:

{% tabs %}
{% tab title="C++" %}

```cpp
auto url = licenseManager->getSSOUrl(); // customer account was set to configuration, URL with authorization code

auto url = licenseManager->getSSOUrl("licensespring"); // customer account was not set to configuration, URL with authorization code

auto url = licenseManager->getSSOUrl(std::string(), false); // customer account was set to configuration, URL with authorization token

auto url = licenseManager->getSSOUrl("licensespring", false); // customer account was not set to configuration, URL with authorization token
```

{% endtab %}

{% tab title="C#" %}

```csharp
var url = licenseManager.GetSSOUrl(); // customer account was set to configuration, URL with authorization code

var url = licenseManager.GetSSOUrl("licensespring"); // customer account was not set to configuration, URL with authorization code

var url = licenseManager.GetSSOUrl(null, false); // customer account was set to configuration, URL with authorization token

var url = licenseManager.GetSSOUrl("licensespring", false); // customer account was not set to configuration, URL with authorization token
```

{% endtab %}

{% tab title="Swift" %}

```swift
let ssoURL = try manager.requestSSOURL()
```

{% endtab %}

{% tab title="Go" %}

```go
sso_resp, err := lh.GetSSOUrl(ctx, "customer account", "use oauth code")
```

{% endtab %}

{% tab title="Java" %}

```java
SSOUrl ssoUrl = licenseManager.getSsoUrl();
```

{% endtab %}
{% endtabs %}

Note that this method sets the passed customer account to the LicenseManager configuration.

#### Alternate SSO URLs

The LicenseSpring platform allows you to set alternate SSO URLs, e.g. one for license activation, and one for license borrowing. The URLs differ only in the redirect\_uri query parameter.

LicenseSpring SDKs expose functions to fetch a list of all available SSO URLs, with the default one being first in the list:

```cpp
 std::vector<std::string> ssoUrls = licenseManager->getAllSSOUrls("licensespring");
```

### Authorization

You can open the SSO URL in the system browser or within the application. After the user enters the login credentials, handle the redirect.

#### System Browser

If you are using the system browser, you can implement reopening the application with the redirect URL as a parameter. To make the application open with the redirect link, add a script that edits the registry, enabling your application to handle LicenseSpring URLs, as a part of the installation process.

Here’s an example of edited registry:

![](https://lh3.googleusercontent.com/Nml8mya19FhFSUs4dQVuJmWGYWNxBRbUMHGfaNLmeUgb-inQO5t2Wff0jfl0W3fmKSoOWnlaM0L2Jy9uZ0hobg-v1Ux4pNrRuGm6thQBMt0Yxgs3Y3W8b6ETjUJPWvd-2uMaOswrlnZvjY6chCjFpg)

![](https://lh3.googleusercontent.com/A7D9Tszf5pOKPx-P-bCYZpKpXyDpXj5bMZEt2Ks3z7d0y7pHuDazMDXk4mCyJ8omoQ93hZ6SEwY3gJmaM8J0NjE6E_P7MhIPfxfdBzyymp2JCwjb4kqXPrOHx-pemkk8lfX7XNFe1Qs6n2mlD2vjcw)

#### Browsing Within the Application

This functionality can be implemented using various libraries and tools such as Qt WebEngine or .NET WebBrowser control. The goal is to wait until the URL changes and retrieve this redirect link.

To learn more about both approaches, see the SSO sample projects we provide along with C++ and .Net SDKs.

### License Activation

When you have the redirect URL, extract the authorization code or token.

{% tabs %}
{% tab title="C++" %}

```cpp
auto query = QUrlQuery( redirectURL.fragment() );
const QString paramName( "code" ); // or "id_token"
if( query.hasQueryItem( paramName) )
{
  auto authorizationData = query.queryItemValue( paramName );
  // activate the license
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
Uri query = new Uri( redirectURL );
string authorizationData = HttpUtility.ParseQueryString( myUri.Query ).Get( "code" ); // or "id_token"
if( !string.IsNullOrEmpty( authorizationData ) )
  // activate the license
```

{% endtab %}

{% tab title="Swift" %}

```swift
let token = try LicenseManager.extractSSOToken(
    from: "redirect url",
    scheme: "licensespring" // for integrity check
)
```

{% endtab %}
{% endtabs %}

Then pass the authorizationData value to the activation method. It allows setting the customer account and specifying whether the authorization data is a code or a token.

{% tabs %}
{% tab title="C++" %}

```cpp
auto license = licenseManager->activateLicense(authorizationData); // customer account was set to configuration, authorizationData is a code

auto license = licenseManager->activateLicense(authorizationData, "licensespring"); // customer account was not set to configuration, authorizationData is a code

auto license = licenseManager->activateLicense(authorizationData, "licensespring", false); // customer account was not set to configuration, authorizationData is a token
```

{% endtab %}

{% tab title="C#" %}

```csharp
var license = licenseManager.ActivateLicense( authorizationData ); // customer account was set to configuration, authorizationData is a code

var license = licenseManager.ActivateLicense( authorizationData, "licensespring" ); // customer account was not set to configuration, authorizationData is a code

var license = licenseManager.ActivateLicense( authorizationData, "licensespring", false ); // customer account was not set to configuration, authorizationData is a token
```

{% endtab %}

{% tab title="Swift" %}

```swift
try manager.activateLicense(ssoToken: token)
```

{% endtab %}
{% endtabs %}

If you want to use an alternate SSO URL, you must pass its redirect URI to the license activation or license borrowing function:

```cpp
// C++ - Use QUrl to extract the redirect URI
auto license = licenseManager->activateLicense(authorizationData, "licensespring", true, redirectURI);
```

### Common Errors

This type of license activation can throw the same errors as a regular activation.

In addition, there are errors specific to single sign-on:

* SSOException - In case the customer was not found or SSO is not enabled.
* SSOTokenException - In case the SSO token is invalid or expired.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.licensespring.com/sdks/tutorials/advanced-usage/single-sign-on.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
