ChaoticPixel.OIDC
1.2.6-alpha
See the version list below for details.
dotnet add package ChaoticPixel.OIDC --version 1.2.6-alpha
NuGet\Install-Package ChaoticPixel.OIDC -Version 1.2.6-alpha
<PackageReference Include="ChaoticPixel.OIDC" Version="1.2.6-alpha" />
paket add ChaoticPixel.OIDC --version 1.2.6-alpha
#r "nuget: ChaoticPixel.OIDC, 1.2.6-alpha"
// Install ChaoticPixel.OIDC as a Cake Addin
#addin nuget:?package=ChaoticPixel.OIDC&version=1.2.6-alpha&prerelease
// Install ChaoticPixel.OIDC as a Cake Tool
#tool nuget:?package=ChaoticPixel.OIDC&version=1.2.6-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 <LATEST>
.NET CLI
> dotnet add package ChaoticPixel.OIDC --version <LATEST>
Paket CLI
> paket add ChaoticPixel.OIDC --version <LATEST>
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:
responseType
- What the response type should be. (Example:"code id_token"
).redirectUrl
- Where the IDP should redirect to with the authorization code. NOTE: This redirect URL has to be configured in your OIDC application.responseMode
- How the IDP should return the data to theredirectUrl
(Example:"form_post"
).scope
- The scope of the Authorization Code (Example:"openid profile"
).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:
scope
- The scope of the Access Token. This should be no more than the scopes of the authorization code (Example:"openid profile"
).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 | Versions 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. |
-
- Microsoft.Owin (>= 3.1.0)
- Newtonsoft.Json (>= 10.0.3)
- Owin (>= 1.0.0)
- System.IdentityModel.Tokens.Jwt (>= 4.0.4.403061554)
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 |
Fixed the simple encryption algorithm.