ChaoticPixel.OIDC 1.2.3-alpha

This is a prerelease version of ChaoticPixel.OIDC.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package ChaoticPixel.OIDC --version 1.2.3-alpha
NuGet\Install-Package ChaoticPixel.OIDC -Version 1.2.3-alpha
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ChaoticPixel.OIDC" Version="1.2.3-alpha" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ChaoticPixel.OIDC --version 1.2.3-alpha
#r "nuget: ChaoticPixel.OIDC, 1.2.3-alpha"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ChaoticPixel.OIDC as a Cake Addin
#addin nuget:?package=ChaoticPixel.OIDC&version=1.2.3-alpha&prerelease

// Install ChaoticPixel.OIDC as a Cake Tool
#tool nuget:?package=ChaoticPixel.OIDC&version=1.2.3-alpha&prerelease

Chaotic Pixel's OIDC Library for .NET v4.7.1

This is an easy-to-use library that was created as a response to the difficult implementation and security concerns of regular libraries. It implements it's own security and token caches, and even token validation, making it easy to use!

Limitations

Currently, the library only supports the Authorization Code flow. More will be added in future builds.

Getting the library

Installing the library is as easy as it gets! Simply open the NuGet Package Manger Console in your project, and type in the following:

Package Manager

PM> Install-Package ChaoticPixel.OIDC -Version 1.2.3-alpha 

.NET CLI

> dotnet add package ChaoticPixel.OIDC --version 1.2.3-alpha 

Paket CLI

> paket add ChaoticPixel.OIDC --version 1.2.3-alpha 

Setting up the Library

First and foremost, you have to get the Open ID Configuration from the server. This is easily done using the OpenIdConfig helper class, as such:

OpenIdConfig config = new OpenIdConfig(clientId, clientSecret);
await config.GetConfig(configEndpointUrl);

NOTE 1: Both clientId and clientSecret are strings. NOTE 2: configEndpointUrl is a string and it represents the URL the library should query for the OIDC configuration. Example: https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

In order to use the library, each user has to have a unique TokenCache attached to them. How you store, retrieve and use the TokenCache is up to you, but this is how you implement it:

TokenCache tokenCache = new TokenCache();

After that, you have to initialize a new OpenIdConfig class. This has to be unique per user as well, as it ties in with the previously created TokenCache to automatically store tokens retrieved. Once again, how you store these is up to you.

OpenIdConnect oidc = new OpenIdConnect(config, tokenCache);

NOTE: config and tokenCache represent the instances of OpenIdConfig and TokenCache we created earlier.

And with that, the OIDC library is ready to use!

Authorization Code Flow

NOTE: All oidc variables refer to the OpenIdConnect instance created above.

Getting the Authorization Code

To get the authorization code we have to redirect the user to the authorization endpoint. For this, we have the GetAuthorizationUrl method which returns a string, containing the fully qualified URL of the authorization endpoint.

string authUrl = oidc.GetAuthorizationUrl(responseType, redirectUrl, responseMode, scope, state);

VARIABLES:

  1. responseType - What the response type should be. (Example: "code id_token").
  2. redirectUrl - Where the IDP should redirect to with the authorization code. NOTE: This redirect URL has to be configured in your OIDC application.
  3. responseMode - How the IDP should return the data to the redirectUrl (Example: "form_post").
  4. scope - The scope of the Authorization Code (Example: "openid profile").
  5. state - The state that should be passed to the IDP. This gets returned with the auth code for validation purposes.

NOTE ABOUT STATE: You should never send important information in the state of the request as it gets passed as cleartext in the URL. Instead, you can use our State Cryptography helper class for security.

Consuming the Authorization Code (and ID Token)

Once the user went through the authorization process, he will be redirected to the URL sent with the request with some data (in our example, an authorization code and an ID token). We have to consume these manually, as such:

string authCode = formData["code"];
string idToken = formData["id_token"];

JwtSecurityToken idTokenJwt = oidc.ValidateToken(idToken);

tokenCache.SetAuthorizationCode(authCode);
tokenCache.SetIdToken(idTokenJwt);

As you can see, in order to get the JWT from the string, we simply validate the ID Token using the built-in method ValidateToken.

Getting an Access Token

Once you have the authorization code, you can get an access token that you can then use as a Bearer authorization header for accessing resources. This is done asynchronously in the background by the library, as such:

await oidc.GetTokens(scope, redirectUri);

VARIABLES:

  1. scope - The scope of the Access Token. This should be no more than the scopes of the authorization code (Example: "openid profile").
  2. redirectUri - Where the tokens should be returned. This doesn't particularly matter, as we're using a POST, however, the URL used here has to be registered in the OIDC application.

Using a Refresh Token

If you add the offline_access scope, you will get a refresh token returned together with the access token. This can be used to get future access tokens without re-authenticating the user, and this is how:

await oidc.RefreshToken(redirectUri);

NOTE: redirectUri is a string.

Other Features

Besides simplifying the use of OIDC, this library also offers a couple of helper classes to aid you in securing the flow.

State Encryption/Decryption

One of the easiest things you can do to secure your exchange is to encrypt the state you pass to the authorization endpoint.

string encryptedState = State.Encrypt(unencryptedState);

NOTE: unencryptedState is a string.

And, presuming the application doesn't reset until the state is returned (as the passwords and salts used to encrypt this are generated randomly upon startup), you can easily validate it as such:

string validatedState = State.Validate(encryptedState);

NOTE: encryptedState is a string.

As part of the validation process, you also get returned the unencrypted state.

RS256 Encryption/Decryption

We also offer an RS256 encryption helper class that allows you to easily encrypt/decrypt any data. It has two processes:

Strong Encryption (randomized password and salt)

The strong encryption process uses a randomized password and salt and, as with the state, if you try to decrypt a previously encrypted string after system restart, it will fail.

string encrypted = RS256.Encrypt(input);

string decrypted = RS256.Decrypt(encrypted);

NOTE: input is a string.

Simple Encryption (user-defined password)

This is a less-secure encryption as it doesn't use any random values, however, encrypted data can be decrypted at a later date as long as the password is known, regardless of system state.

string encrypted = RS256.Encrypt(input, password);

string decrypted = RS256.Decrypt(encrypted, password);

NOTE: Both input and password are of type string.

Product Compatible and additional computed target framework versions.
.NET Framework net461 is compatible.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.12-beta 747 1/8/2018
1.2.19-alpha 761 12/25/2017
1.2.6-alpha 740 12/21/2017
1.2.3-alpha 957 12/20/2017
1.2.2-alpha 749 12/20/2017
1.2.1-alpha 758 12/5/2017
1.2.0-alpha 752 12/5/2017
1.1.0-inDev 751 11/29/2017
1.0.1-inDev 766 11/29/2017
1.0.0-inDev 889 11/28/2017

Adds an simple encryption algorithm that takes a custom password.