![]() |
VOOZH | about |
dotnet add package Tenduke.Client.WinForms --version 4.0.5
NuGet\Install-Package Tenduke.Client.WinForms -Version 4.0.5
<PackageReference Include="Tenduke.Client.WinForms" Version="4.0.5" />
<PackageVersion Include="Tenduke.Client.WinForms" Version="4.0.5" />Directory.Packages.props
<PackageReference Include="Tenduke.Client.WinForms" />Project file
paket add Tenduke.Client.WinForms --version 4.0.5
#r "nuget: Tenduke.Client.WinForms, 4.0.5"
#:package Tenduke.Client.WinForms@4.0.5
#addin nuget:?package=Tenduke.Client.WinForms&version=4.0.5Install as a Cake Addin
#tool nuget:?package=Tenduke.Client.WinForms&version=4.0.5Install as a Cake Tool
Client library for .NET Windows Forms (WinForms) applications, for using services of the 10Duke Identity and Entitlement. Main features are:
The client library is available as a NuGet package. An example for installing the client library using NuGet Package Manager:
dotnet add package Tenduke.Client.WinForms
Install-Package Tenduke.Client.WinForms
Class Tenduke.Client.WinForms.EntClient is the main implementation
class that supports integrating a WinForms application to 10Duke
Identity and Entitlement service. Configuration and features of
Tenduke.Client.WinForms.EntClient are introduced below.
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 OpenID Connect Authorization Code Grant flow with PKCE. 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.
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.WinForms.EntClient.
The browser form showing the embedded browser can be customized by
handling the RaiseInitializeBrowserForm event and setting form
properties in the event handler. This example changes the form title:
...
entClient.RaiseInitializeBrowserForm += HandleInitializeBrowserForm;
...
private void HandleInitializeBrowserForm(object sender, InitializeBrowserFormEventArgs e)
{
e.WebBrowserForm.Text = "Acme login";
}
After initializing the CEFSharp embedded browser component, the
Tenduke.Client.WinForms.EntClient can be initialized by calling:
Tenduke.Client.WinForms.EntClient.Initialize(resolverArgs);
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 = "https://my-test-idp.10duke.net/user/oauth20/authz",
TokenUri = "https://my-test-idp.10duke.net/user/oauth20/token",
UserInfoUri = "https://my-test-idp.10duke.net/user/info",
ClientID = "my-client-id",
ClientSecret = null,
RedirectUri = "oob:MyTestApplication",
Scope = "openid profile email",
SignerKey = [Public key of 10Duke Entitlement service],
ShowRememberMe = true,
UsePkce = true,
AllowInsecureCerts = false
};
Here, the Uris must point to an actual 10Duke Entitlement service
deployment. ClientID, ClientSecret (only used if UsePkce is
false) 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, where
the string can be either an RSA public key in PEM format or URL of
server JWKS endpoint:
var publicKey = await Tenduke.Client.Util.CryptoUtil.ReadFirstRsaPublicKey(publicKeyOrJwksUrl, new HttpClient());
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:
Tenduke.Client.WinForms.EntClient.Shutdown();
This is a static method call to be called once in the client application lifecycle.
User authentication is started with this call:
entClient.AuthorizeSync();
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;
Example user info and license requests are given below:
var userInfo = await entClient.UserInfoApi.GetUserInfoAsync();
This call returns an object with OpenID Connect user info.
var tokenResponse = await entClient.AuthzApi.CheckOrConsumeAsync("MyLicense", true, ResponseType.JWT);
The call above 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.
var tokenResponse = await entClient.AuthzApi.CheckOrConsumeAsync(
"MyLicense",
true,
ResponseType.JWT,
ConsumptionMode.Cache,
new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("licenseId", licenseId) });
This example specifies some more parameters to the consumption request.
The last parameter shown in the example can be used for giving any
additional claims understood by the license consumption endpoint.
Standard additional claims include licenseId and entitlementId that
can be used for explicitly selecting the license or entitlement to
consume. In basic use cases for consuming if a valid license is found,
these parameters are not required.
License consumption requests compute a computer id that is sent with the
consumption requests in order to identify the client hardware. Computer
id can be customized by setting ComputerIdentityConfig, for example
the following configuration makes computer id computation use
FIPS-compliant SHA256 hash algorithm:
entClient.ComputerIdentityConfig = new ComputerIdentityConfig() { HashAlg = Desktop.Util.ComputerIdentity.HashAlg.SHA256 };
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.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 net8.0-windows7.0 is compatible. net9.0-windows net9.0-windows was computed. net9.0-windows7.0 net9.0-windows7.0 is compatible. net10.0-windows net10.0-windows was computed. |
| .NET Framework | net462 net462 is compatible. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 is compatible. net48 net48 was computed. net481 net481 is compatible. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.5 | 329 | 10/6/2025 |
| 4.0.3 | 420 | 4/29/2025 |
| 4.0.2 | 546 | 10/30/2024 |
| 4.0.1 | 363 | 7/16/2024 |
| 4.0.0 | 445 | 3/11/2024 |
| 3.6.0 | 310 | 9/20/2023 |
| 3.4.3 | 698 | 6/10/2022 |
| 3.4.2 | 667 | 2/14/2022 |
| 3.4.0 | 644 | 2/11/2022 |
| 3.3.1 | 512 | 1/3/2022 |
| 3.2.1 | 684 | 3/10/2021 |
| 3.1.1 | 721 | 11/30/2020 |
| 3.1.0 | 781 | 10/30/2020 |
| 3.0.1 | 794 | 4/2/2020 |
| 3.0.0 | 769 | 4/2/2020 |
| 2.3.4 | 743 | 3/16/2020 |
| 2.3.3 | 776 | 3/12/2020 |
| 2.3.2 | 807 | 12/9/2019 |