kcoidc

package module
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2020 License: AGPL-3.0-or-later Imports: 12 Imported by: 4

README

Kopano OpenID Connection validation library

This project implements a C shared library with a public API to validate Kopano Konnect tokens (JSON Web Tokens).

In the python subdirectory a CPython module is available which makes all the functions from the C shared library usable from Python.

Also this project can be used directly from Go as an importable module.

Compiling

Make sure you have Go 1.13 or later installed. This project uses Go modules.

As this is a C library, it is furthermore assumed that there is a working C compiler toolchain in your path which includes autoconf and make.

git clone <THIS-PROJECT> libkcoidc
cd libkcoidc
./bootstrap.sh
./configure
make

This will produce the compiled library .so and the matching C header file in the ./.libs directory.

Environment variables

Environment variable Description
KCOIDC_DEBUG When set, libkcoidc will print debug info to stdout
Compile python module

The Python module supports Python 3 and Python 2. By default it compiles with whatever Python in your path as python3, python or python2 whichever is found first. Use the PYTHON environment variable to compile for a specific Python.

PYTHON=python3 make python
Use a Go module
import "stash.kopano.io/kc/libkcoidc"

provider, err := kcoidc.NewProvider(nil, nil, false)

Errors

The library returns error codes in the form of integer values. Please see errors.go for a list.

Examples

This project contains C example applications in the examples folder which can be used to test the library form the commandline.

export TOKEN_VALUE='eyJhbGciOiJSUzI1NiIsImtpZCI6ImRlZmF1bHQiLCJ0eXAiOiJKV1QifQ.eyJrYy5pc0FjY2Vzc1Rva2VuIjp0cnVlLCJrYy5hdXRob3JpemVkU2NvcGVzIjpbIm9wZW5pZCIsInByb2ZpbGUiLCJlbWFpbCJdLCJhdWQiOiJwbGF5Z3JvdW5kLXRydXN0ZWQuanMiLCJleHAiOjE1MTYyOTEzMTEsImlhdCI6MTUxNjI5MDcxMSwiaXNzIjoiaHR0cHM6Ly9tb3NlNDo4NDQzIiwic3ViIjoidWlkPXVzZXIxLG91PXVzZXJzLGRjPWZhcm1lcixkYz1sYW4iLCJrYy5pZGVudGl0eSI6eyJrYy5pLmRuIjoiSm9uYXMgQnJla2tlIiwia2MuaS51biI6InVzZXIxIn19.A28u8R_Euv492qVsIEub5836qo3wzinM8up78vFVEZ1o48PA7-7LrNqJ14EfC_Me-vd2QrW6GtofScSreLUrnqTACYnG6G7R3RVJhCjiuMd6eOFnLAjLl-2ubGa8DYHTK4k9p_Ynuv06AEvCqlplqtK5Mlg0OIbLTxfKxyg77quH6OA0MUbvndKG5t1S9ADj3v39OlSzdpnvSV8LKs7soCtXfotR6Bg8xSXdBI-tNhrjSbzCI2BaghVSdaRbQkcTBe3W5KimaBjbBpTIH74ViFJYzIGOMmGKr__CH4KYn_F-r5ULyVE7m4Qn4K6wqt17TXR3xG6T7Hhs19xVvzoGKg'
make examples && KCOIDC_DEBUG= bin/validate-c 'https://mose4:8443' "$TOKEN_VALUE" && echo 'yay' || echo 'nay'

First parameter of the validate example binary is the full qualified OpenID Connect Issuer Identifier which is usually a https:// URL without path. The second parameter is a string value which will be used as token. So any encoded JWT can be passed here.

Similarly there is also a simple C++ benchmark.

make examples && KCOIDC_DEBUG= bin/benchmark-cpp 'https://mose4:8443' "$TOKEN_VALUE" && echo 'yay' || echo 'nay'
> Info : using 8 threads with 100000 runs per thread
> Info : thread 2 started ...
> Info : thread 3 started ...
> Info : thread 5 started ...
> Info : thread 1 started ...
> Info : thread 4 started ...
> Info : thread 6 started ...
> Info : thread 7 started ...
> Info : thread 8 started ...
> Info : thread 1 done:100000 failed:0
> Info : thread 2 done:100000 failed:0
> Info : thread 4 done:100000 failed:0
> Info : thread 3 done:100000 failed:0
> Info : thread 7 done:100000 failed:0
> Info : thread 6 done:100000 failed:0
> Info : thread 8 done:100000 failed:0
> Info : thread 5 done:100000 failed:0
> Time : 19.101s
> Rate : 41882.6 op/s
yay

So on my machine (Intel(R) Core(TM) i7-3930K CPU @ 3.20GHz), this gives around 42000 validations per second with 8 parallel threads.

The same applications are also implemented in Python and Go for your reference/example.

Documentation

Index

Constants

View Source
const (
	IsAccessTokenClaim  = "kc.isAccessToken"
	IsRefreshTokenClaim = "kc.isRefreshToken"

	IdentityClaim         = "kc.identity"
	IdentifiedUserIDClaim = "kc.i.id"
	IdentifiedUserIsGuest = "kc.i.guest"

	AuthorizedScopesClaim = "kc.authorizedScopes"
	AuthorizedClaimsClaim = "kc.authorizedClaims"
)

Token claims used by Kopano Konnect.

View Source
const (
	TokenTypeStandard  int = 0
	TokenTypeKCAccess  int = 1
	TokenTypeKCRefresh int = 2
)

Token types as int.

View Source
const StatusSuccess = ErrStatusNone

StatusSuccess is the success response as returned by this library.

Variables

View Source
var ErrStatusTextMap = map[ErrStatus]string{
	ErrStatusUnknown:                      "Unknown",
	ErrStatusInvalidIss:                   "Invalid Issuer Identifier Value",
	ErrStatusAlreadyInitialized:           "Already Initialized",
	ErrStatusNotInitialized:               "Not Initialized",
	ErrStatusTimeout:                      "Timeout",
	ErrStatusTokenUnexpectedSigningMethod: "Unexpected Token Signing Method",
	ErrStatusTokenMalformed:               "Malformed Token",
	ErrStatusTokenExpiredOrNotValidYet:    "Token Expired Or Not Valid Yet",
	ErrStatusTokenUnknownKey:              "Unknown Token Key",
	ErrStatusTokenInvalidSignature:        "Invalid Token Signature",
	ErrStatusTokenValidationFailed:        "Token Validation Failed",
	ErrStatusClosed:                       "Is Closed",
	ErrStatusWrongInitialization:          "Wrong Initialization",
	ErrStatusMissingRequiredScope:         "Missing required scope",
}

ErrStatusTextMap maps ErrStatusos to readable names.

Functions

func AuthenticatedUserIDFromClaims

func AuthenticatedUserIDFromClaims(claims *ExtraClaimsWithType) (string, bool)

AuthenticatedUserIDFromClaims extracts extra Kopano Connect identified claims from the provided extra claims, returning the authenticated user id.

func AuthenticatedUserIsGuest

func AuthenticatedUserIsGuest(claims *ExtraClaimsWithType) bool

AuthenticatedUserIsGuest extract extra Kopano Connect identified claims from the provided extra claims, returning if the claims are for a guest or not.

func AuthorizedClaimsFromClaims

func AuthorizedClaimsFromClaims(claims *ExtraClaimsWithType) map[string]interface{}

AuthorizedClaimsFromClaims returns the authorized claims as map from the provided extra claims.

func AuthorizedScopesFromClaims

func AuthorizedScopesFromClaims(claims *ExtraClaimsWithType) map[string]bool

AuthorizedScopesFromClaims returns the authorized scopes as bool map from the provided extra claims.

func ErrStatusText

func ErrStatusText(code ErrStatus) string

ErrStatusText returns a text for the ErrStatus. It returns the empty string if the code is unknown.

func RequireScopesInClaims

func RequireScopesInClaims(claims *ExtraClaimsWithType, requiredScopes []string) error

RequireScopesInClaims returns nil if all the provided scopes are found in the provided claims. Otherwise an error is returned.

func SplitStandardClaimsFromMapClaims

func SplitStandardClaimsFromMapClaims(claims *ExtraClaimsWithType) (*jwt.StandardClaims, error)

SplitStandardClaimsFromMapClaims removes all JWT standard claims from the provided map claims and returns them.

Types

type ErrStatus

type ErrStatus uint64

ErrStatus is the Error type as used by kcoidc.

const (
	ErrStatusNone              = iota
	ErrStatusUnknown ErrStatus = iota + (1 << 8)
	ErrStatusInvalidIss
	ErrStatusAlreadyInitialized
	ErrStatusNotInitialized
	ErrStatusTimeout
	ErrStatusTokenUnexpectedSigningMethod
	ErrStatusTokenMalformed
	ErrStatusTokenExpiredOrNotValidYet
	ErrStatusTokenUnknownKey
	ErrStatusTokenInvalidSignature
	ErrStatusTokenValidationFailed
	ErrStatusClosed
	ErrStatusWrongInitialization
	ErrStatusMissingRequiredScope
)

ErrStatusors as defined by this library.

func (ErrStatus) Error

func (errStatus ErrStatus) Error() string

type ExtraClaimsWithType

type ExtraClaimsWithType jwt.MapClaims

ExtraClaimsWithType is a MapClaims with a specific type.

func (*ExtraClaimsWithType) KCTokenType

func (claims *ExtraClaimsWithType) KCTokenType() int

KCTokenType returns the numeric type of the accociated claims.

func (*ExtraClaimsWithType) Valid

func (claims *ExtraClaimsWithType) Valid() error

Valid satisfies the jwt.Claims interface.

type Logger added in v0.9.0

type Logger interface {
	Printf(string, ...interface{})
}

A Logger defines a simple logging interface for pluggable loggers used by this module.

var DefaultLogger Logger = nil

DefaultLogger is the logger used by this library if no other is explicitly specified.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

A Provider is a representation of an OpenID Connect Provider (OP).

func NewProvider

func NewProvider(client *http.Client, logger Logger, debug bool) (*Provider, error)

NewProvider creates a new Provider with the provider HTTP client. If no client is provided, http.DefaultClient will be used.

func (*Provider) BuildDate added in v0.9.0

func (p *Provider) BuildDate() string

BuildDate returns the build data string of this module.

func (*Provider) FetchUserinfoWithAccesstokenString

func (p *Provider) FetchUserinfoWithAccesstokenString(ctx context.Context, tokenString string) (map[string]interface{}, error)

FetchUserinfoWithAccesstokenString fetches the the userinfo result of the accociated provider for the provided access token string.

func (*Provider) Initialize

func (p *Provider) Initialize(ctx context.Context, issuer *url.URL) error

Initialize initializes the associated Provider with the provided issuer.

func (*Provider) Uninitialize

func (p *Provider) Uninitialize() error

Uninitialize uninitializes the associated Provider.

func (*Provider) ValidateTokenString

func (p *Provider) ValidateTokenString(ctx context.Context, tokenString string) (string, *jwt.StandardClaims, *ExtraClaimsWithType, error)

ValidateTokenString validates the provided token string value with the keys of the accociated Provider and returns the authenticated users ID as found in the claims, the standard claims and all extra claims.

func (*Provider) Version added in v0.9.0

func (p *Provider) Version() string

Version returns the runtime version string of this module.

func (*Provider) WaitUntilReady

func (p *Provider) WaitUntilReady(ctx context.Context, timeout time.Duration) error

WaitUntilReady blocks until the associated Provider is ready or timeout.

Directories

Path Synopsis
cmd
internal
lib

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL