Kinde.SDK
0.0.1
Prefix Reserved
See the version list below for details.
dotnet add package Kinde.SDK --version 0.0.1
NuGet\Install-Package Kinde.SDK -Version 0.0.1
<PackageReference Include="Kinde.SDK" Version="0.0.1" />
paket add Kinde.SDK --version 0.0.1
#r "nuget: Kinde.SDK, 0.0.1"
// Install Kinde.SDK as a Cake Addin #addin nuget:?package=Kinde.SDK&version=0.0.1 // Install Kinde.SDK as a Cake Tool #tool nuget:?package=Kinde.SDK&version=0.0.1
Kinde SDK
Setup and configuration
Identity provider configuration contains these parameters:
- Domain. Base domain used for authorization. must be subdomain of kinde.com. F.E. testauth.kinde.com
- ReplyUrl. Unused for client credentials, but used as callback url for other flows. May be null for client credentials
- LogoutUrl. Url for redirection after logout.
Additional requirements (based on flow)
- ClientID, required.
- ClientSecret, required.
- Scope, required.
- State, optional. Can be set to null, then will be autogenerated. <b> Note, that state parameter must not be constant. It must be random for each call.</b>
- Code verifier generic parameter, required. Use inbuilt SHA256CodeVerifier, or create other one if needed.
SDK supports configuration from appsetings.json. Also, you can write your own implementation of IAuthorizationConfigurationProvider
and IIdentityProviderConfigurationProvider
.
Configuration example:
"ApplicationConfiguration": {
"Domain": "https://testauth.kinde.com",
"ReplyUrl": "https://localhost:7165/home/callback",
"LogoutUrl": "https://localhost:7165/home"
},
"DefaultAuthorizationConfiguration": {
"ConfigurationType": "Kinde.Api.Models.Configuration.PKCES256Configutation",
"Configuration": {
"State": null,
"ClientId": "reg@live",
"Scope": "openid offline",
"GrantType": "code id_token token",
"ClientSecret": "<my secret>"
}
},
Also, you should register configuration providers using .net DI:
builder.Services.AddTransient<IAuthorizationConfigurationProvider, DefaultAuthorizationConfigurationProvider>();
builder.Services.AddTransient<IApplicationConfigurationProvider, DefaultApplicationConfigurationProvider>();
PKCES256Configutation is most complicated configuration and contains all necessary properties. Configuration for Authentication code is same and for Client credentials State is not applicable. But it is not mandatory to remove it. All availiable types are:
- Kinde.Api.Models.Configuration.PKCES256Configutation
- Kinde.Api.Models.Configuration.AuthorizationCodeConfiguration
- Kinde.Api.Models.Configuration.ClientCredentialsConfiguration
Besides configuration, all code approach is quite similar. Only difference is if authorization flow requires user redirection or not.
For Client configuration Authorize()
call is enough for authoriztion.
For others (PKCE and Authorization code) you should handle redirection to Kinde (as IdP) and handle callback to end authorization.
1. Login with no redirection, using Client credentials flow
Don't use autogenerated constructor without <code>IIdentityProviderConfiguration</code> parameter. This will throw exceptions.
For not web application only client credentials flow can be used. Because other flows requires user interaction via browser. Example: <br>
var client = new Kinde.KindeClient(
new IdentityProviderConfiguration("https://testauth.kinde.com", "https://test.domain.com/callback", "https://test.domain.com/logout"),
new KindeHttpClient());
await client.Authorize(new ClientCredentialsConfiguration("clientId_here","openid offline any_other_scope", "client secret here"));
// Api call
// vvv
var myOrganization = client.CreateOrganizationAsync("My new best organization");
After this you can call any api methods on this instance.
2. Login with redirection, using PKCE256 flow or Authorization code
Don't use autogenerated constructor without <code>IIdentityProviderConfiguration</code> parameter. This will throw exceptions.
For web applications api clients should be connected to user session. To keep them sync use <code>KindeClientFactory</code>. I t has thread safe dictionary to save client instances. It is highly recommended to use Session Id or something like this as a key for instance.
Example:<br>
public async Task<IActionResult> Login()
{
// We need some artificial id to correlate user session to client instance
//NOTE: Session.Id will be always random, we need to add something to session to make it persistent.
string correlationId = HttpContext.Session?.GetString("KindeCorrelationId");
if (string.IsNullOrEmpty(correlationId))
{
correlationId = Guid.NewGuid().ToString();
HttpContext.Session.SetString("KindeCorrelationId", correlationId);
}
// Get client's instance...
var client = KindeClientFactory.Instance.GetOrCreate(correlationId, _appConfigurationProvider.Get());
// ...and authorize it
await client.Authorize(_authConfigurationProvider.Get());
// if auth flow is not ClientCredentials flow, we need to redirect user to another page
if (client.AuthotizationState == Api.Enums.AuthotizationStates.UserActionsNeeded)
{
// redirect user to login page
return Redirect(await client.GetRedirectionUrl(correlationId));
}
return RedirectToAction("Index");
}
This code won't authenticate user complletely. We should wait for data on callback endpoint and execute this: <br>
public IActionResult Callback(string code, string state)
{
Kinde.KindeClient.OnCodeRecieved(code, state);
string correlationId = HttpContext.Session?.GetString("KindeCorrelationId");
var client = KindeClientFactory.Instance.Get(correlationId); //already authorized instance
// Api call
// vvv
var myOrganization = client.CreateOrganizationAsync("My new best organization");
return RedirectToAction("Index");
}
Register user
User registration is same as authorization. With one tiny difference:
public async Task<IActionResult> SignUp()
{
string correlationId = HttpContext.Session?.GetString("KindeCorrelationId");
if (string.IsNullOrEmpty(correlationId))
{
correlationId = Guid.NewGuid().ToString();
HttpContext.Session.SetString("KindeCorrelationId", correlationId);
}
var client = KindeClientFactory.Instance.GetOrCreate(correlationId, _appConfigurationProvider.Get());
await client.Authorize(_authConfigurationProvider.Get(), true); //<--- Pass true to register user
if (client.AuthotizationState == Api.Enums.AuthotizationStates.UserActionsNeeded)
{
return Redirect(await client.GetRedirectionUrl(correlationId));
}
return RedirectToAction("Index");
}
Logout
Logout has two steps: local cache cleanup and token revocation on Kinde side. So, client.Logout() method sholud be called. This method returns redirect url for token revocation. User should be redirected to it.
Logout example:
public async Task<IActionResult> Logout()
{
string correlationId = HttpContext.Session?.GetString("KindeCorrelationId");
var client = KindeClientFactory.Instance.GetOrCreate(correlationId, _appConfigurationProvider.Get());
var url = await client.Logout();
return Redirect(url);
}
Token renewal
Token will renew automatically in background. If you want to do it manually, call Renew method. Example:
public async Task<IActionResult> Renew()
{
string correlationId = HttpContext.Session?.GetString("KindeCorrelationId");
var client = KindeClientFactory.Instance.GetOrCreate(correlationId, _appConfigurationProvider.Get());
await client.Renew();
return RedirectToAction("Index");
}
More usage examples can be found in Kinde.DemoMvc project.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.Extensions.Configuration (>= 6.0.1)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Newtonsoft.Json (>= 13.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.