Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


WPF client library for 10Duke Identity and Entitlement

Client library for .NET Windows Presentation Foundation (WPF) applications, for using services of the 10Duke Identity and Entitlement. Main features are:

  • Authentication and authorization with OAuth 2.0 and OpenID Connect

  • Querying user info

  • Checking and consuming licenses

  • Releasing consumed licenses

  • Checking end-user permissions


The client library is available as a NuGet package. An example for installing the client library using NuGet Package Manager:

Installation with NuGet PackageManager
Install-Package Tenduke.Client.WPF

Basic usage

Class Tenduke.Client.WPF.EntClient is the main implementation class that supports integrating a WPF application to 10Duke Identity and Entitlement service. Configuration and features of Tenduke.Client.WPF.EntClient are introduced below.

Authentication and authorization

When using 10Duke Identity, the client application delegates authentication to the 10Duke Identity Provider. For using 10Duke APIs, including Entitlement, the client application must authorize the API calls by presenting an OAuth 2.0 access token. The simplest way to achieve both authentication (and Single Sign-On) and authorization is to use OpenID Connect (OIDC). OpenID Connect is based on OAuth 2.0, and as a result of the sign-on flow both identity and authorization are established.

Authentication and authorization are implemented using OAuth 2.0 Authorization Code Grant flow with OpenID Connect. An embedded browser is used for user interaction, most notably for the login prompt. This approach is secure, flexible and unleashes advanced use cases like federated authentication.

Embedded browser

The client library uses the CEFSharp library that is based on Chromium Embedded Framework. All the required components are bundled with the client library. CEFSharp must be initialized when the client application starts, before the browser window is opened for the first time, with the following method call:

var resolverArgs = Tenduke.Client.Desktop.Util.CefSharpUtil.AddAssemblyResolverForCefSharp();

This initialization call is a static call and must be called once in the lifecycle of the client application. The returned resolverArgs object is needed later for initializing the Tenduke.Client.WPF.EntClient.

EntClient initialization and clean-up

After initializing the CEFSharp embedded browser component, the Tenduke.Client.WPF.EntClient can be initialized by calling:


Here, resolverArgs is the object returned by the CEFSharp initialization call described above. Also this initialization call is a static method call that must be done once in the client application lifecycle.

After static initialization an instance of EntClient can be created:

var entClient = new EntClient() { OAuthConfig = myOAuthConfig };

Here, myOAuthConfig is an instance of Tenduke.Client.Config.AuthorizationCodeGrantConfig, for instance:

var myOAuthConfig = new AuthorizationCodeGrantConfig()
    AuthzUri = "",
    TokenUri = "",
    UserInfoUri = "",
    ClientID = "my-client-id",
    ClientSecret = "my-client-secret",
    RedirectUri = "oob:MyTestApplication",
    Scope = "openid profile email",
    SignerKey = [Public key of 10Duke Entitlement service]

Here, the Uris must point to an actual 10Duke Entitlement service deployment. ClientID, ClientSecret and RedirectUri are standard OAuth parameters and they must match values configured in the 10Duke Entitlement service deployment. Scope is the OAuth / OpenID Connect scope required by the client application, usually at least the openid and profile scope should be specified. SignerKey is the RSA public key that is used for verifying signatures of tokens issued by the 10Duke Entitlement service. The following utility is provided for reading an RSA key from string:

var publicKey = Tenduke.Client.Util.CryptoUtil.ReadRsaPublicKey(publicKeyAsString);

Now, the EntClient instance is ready to be used for user authentication, license requests etc.

When the client application is closing, the following call must be executed to shut down EntClient and clean up resources:


This is a static method call to be called once in the client application lifecycle.

User authentication and OAuth authorization

User authentication is started with this call:


This starts the OAuth 2.0 / OpenID Connect flow and opens a modal window with an embedded browser. User logs in in this window. What happens next is fully handled by the client library: Internally a standard OAuth redirect is executed to the specified redirect URI. Example redirect URI oob:MyTestApplication is used above, but any URI with a custom schema can be used. By convention, the oob: (Out Of Band) is used in most cases.

When login is completed the modal window closes and the EntClient instance holds the login state. The following call tells if the login has been completed successfully:

var success = entClient.IsAuthorized();

Full OAuth authorization data included OpenID Connect ID Token is stored in the Authorization property:

var authorizationInfo = entClient.Authorization;

Using the client to make 10Duke API calls

Example user info and license requests are given below:

User info request
var userInfo = await entClient.UserInfoApi.GetUserInfoAsync();

This call returns an object with OpenID Connect user info.

Consume license
var tokenResponse = await entClient.AuthzApi.CheckOrConsumeAsync("MyLicense", true, ResponseType.JWT);

This call returns a Tenduke.Client.EntApi.Authz.AuthorizationDecision object that describes an authorization decision, returned as a signed JWT token. The AuthorizationDecision indicates if a license lease has been granted (and a license seat has been taken), and the client application can rely on the AuthorizationDecision until the object expires. Expiration of the object is the same as expiration of the returned JWT token and expiration of the license lease.

Release license
var tokenResponse = await entClient.AuthzApi.ReleaseLicenseAsync(tokenResponse["jti"], ResponseType.JWT);

This call is used for returning a consumed lease (license seat) back to the license pool.

You can’t perform that action at this time.