WebApiSkeleton.Security
1.1.2
dotnet add package WebApiSkeleton.Security --version 1.1.2
NuGet\Install-Package WebApiSkeleton.Security -Version 1.1.2
<PackageReference Include="WebApiSkeleton.Security" Version="1.1.2" />
<PackageVersion Include="WebApiSkeleton.Security" Version="1.1.2" />
<PackageReference Include="WebApiSkeleton.Security" />
paket add WebApiSkeleton.Security --version 1.1.2
#r "nuget: WebApiSkeleton.Security, 1.1.2"
#:package WebApiSkeleton.Security@1.1.2
#addin nuget:?package=WebApiSkeleton.Security&version=1.1.2
#tool nuget:?package=WebApiSkeleton.Security&version=1.1.2
WebApiSkeleton.Security
WebApiSkeleton.Security is a NuGet package that provides tooling for authentication and authorization in .NET
application or as a separate service.
Project description
WebApiSkeleton.Security.Core- contains base models and abstractions that are used to implement core functionality, such as:- Internal database models and classes to interact with it;
- Authentication and authorization settings (encryption, JWT parameters);
- Models that describe authorization process (Role, User, Permission, Claim, etc.);
- Services that are used to query the data or do actions on stored data.
WebApiSkeleton.Security- security core implementation that is based on MediatR and otherWebApiSkeletonMediatR-related packages. The main features are:- Requiring authorization on MediatR requests by
using
SecurityRequirementsAttributeor persisting them in database; - Authentication and authorization process handling using MediatR pipeline behavior;
- Applying custom authorization rules in authorization process;
- User bruteforce detection using MediatR pipeline behavior;
- Redis caching for permissions and roles.
- Requiring authorization on MediatR requests by
using
NOTE: Core module does not make any validation or existence checks. All validation must be made in core implementations.
Usage
Register the dependencies
Core dependencies
Required core dependencies are added to DI container by using AddSecurityCore method. All configuration is done by
modifying SecurityConfiguration object.
The following settings are required and will throw if not specified or configured with errors:
RedisConnectionSettings- contains the address of Redis database and database number to use;DatabaseOptions- DbContext configuration action and the setting of cross-request MediatR transactions (highly recommended to always be true);JwtSettings- JWT token settings that are used in creation process. Encryption key is required ifUseJwtEncryptionis true on configuration Has default values for some fields inTokenValidationParameterssuch as:IssuerSigningKeywill always automatically be set toSymmetricSecurityKeyusing providedSigningKey;ValidateIssuerSigningKeywill always be true;ValidateLifetimewill always be true;ClockSkewwill always be set toTimeSpan.Zero;- If
UseJwtEncryptionis true in configuration, thenTokenDecryptionKeywill always automatically be set toSymmetricSecurityKeyusing providedEncryptionKey;
PasswordEncryptionKey- encryption key that is used for password hashing
Settings with default values that can be overriden if needed:
IncludeUserClaimsInJwt- default is false. Not recommended to use if users will have too much claims as JWT token would not fit in cookie;UseJwtEncryption- default is false. Highly recommended to use but disabled for more clear debugging and testing of the JWT's;ValidationSettings- settings to validate usernames and passwords (not used in core module, left to use in implementations using the core).- Username default requirements:
- Only latin symbols are allowed;
- Digits and underscore are allowed;
- Minimum length of 5 symbols;
- Maximum length of 15 symbols;
- Password default requirements:
- At least one lowercase letter required;
- At least one uppercase letter required;
- At least one digit required;
- At least one non-alphanumeric symbol required (@$!%*#?&)
- Minimum length of 10 symbols;
- Username default requirements:
VerificationSettings- settings of email verification code. Verification code type and time to live can be set.- Default verification code type is 6 digit integer;
- Type can be changed to GUID or random string.
MediatR implementation dependencies
Required MediatR implementation dependencies are added to DI container by using AddSecurityMediatR method. The one
setting that can be changed is ContractPermissionStorageSettings that defines contract authorization requirements are
stored in database or not.
NOTE: this is the only one method that automatically adds the bruteforce detection pipeline behavior
for AuthorizationCommand. If you want to apply any pipeline behaviors before bruteforce check then apply them before
calling this method.
Register pipeline behaviors
There are two ways to add Permission pipeline behaviors to DI to work correctly:
- Call
AddPermissionPipelineBehaviorsForRequestsInAssembliesextension method onIServiceProvider. This way passed assemblies will be scanned for classes (or records) that implementIAuthorizedRequest<T>interface and automatically add them to DI. If non-generic interface used then the call will throw anInvalidOperationException.- NOTE: in this case
PermissionBehaviorfor request is automatically added, so it is highly recommended to mind the order ofIPipelineBehaviorimplementations added to DI.
- NOTE: in this case
- Create
PermissionBehaviorimplementation type by usingPermissionBehaviorCreator.GetPermissionPipelineBehaviorForRequestmethod returnspipelineBehavioras a service type andpermissionBehavioras implementation type. After the tuple is returned, it is possible to manually add pipelines in DI in the required order.
Set up validation
MediatR implementation module contains validators for all of the commands using FluentValidation that are
automatically added to DI container.
Although, ValidationBehavior from WebApiSkeleton.Contracts.Validation is not automatically added and must be added
manually using methods found
in documentation.
NOTE: It is highly recommended to add ValidationBehavior after PermissionBehavior because of performance and
security reasons.
Configure and migrate database schema
Manage authentication and authorization
Authentication and authorization for requests are automatically managed
by PermissionBehavior by
using IUserIdentity abstraction.
The identity model is provided by implementation
of IUserIdentityProvider.
There is no default implementation within WebApiSkeleton.Security modules. As an example there
is HttpUserIdentityProvider for ASP.NET Core
that gets the UserIdentity from HttpContext.
NOTE: if there is no implementation for IUserIdentityProvider
registered, AnonymousUserIdentity is
always returned.
Module interaction
Using core package, all interaction is done by using output services. These services do not implement any validity checks, so database-related exception are likely to be thrown if violating indexes and rules.
MediatR implementation module has all operations implemented in contracts.
All validation is done on request execution and will return faulted Result<T> if something is gone wrong.
NOTE: for validation to work, validation must be correctly configured.
Permissions
Permission can be granted to any user or role with
corresponding PermissionMode. Restrict permission on
any of entities completely forbids the usage of this permission (even if it is Allowed in any other).
Custom permissions
Custom permission is the user-defined permission
requirement. It has a type name that defines what it is used for. Key property defines the entity which is given the
permission.
Contract permissions
MediatR request authorization requirements can be added in two ways:
SecurityRequirementsAttribute- attribute defines compile-time permission and role names that are required to execute the request
[SecurityRequirements(RequiredPermissions = ["SetUserPassword"], RequiredRoles = ["SecurityAdmin"])]
public sealed record SetUserPasswordCommand(UserLoginOrIdFinder UserLoginOrId, string Password) : IAuthorizedRequest<None>, IValidatableRequest<None>;
ContractPermissionStorageSettings- ifStoreContractPermissionsis set totrue, permissions for contract names can be persisted in database and then used inPermissionBehaviorto get required permissions. NOTE: in this case, contract permission is a custom permission type with default type name"ContractPermission", which can be changed inCustomPermissionTypeNameproperty.
Create authorization rules
Example
Example projects for the service using WebApiSkeleton.Security MediatR implementation with different SQL providers can
be found in examples directory.
Versioning
All projects are versioned using following format: major.minor.patch. Versioning rules for all projects:
patchneeds to be incremented when any minor change is made to the project, such as bugfixes or small project-specific features addedminorneeds to be incremented when new template-wide feature is implemented. In this case all of the projects must have the same version setmajorneeds to be incremented when theWebApiSkeletontemplate has experienced significant changes, that need to upgrade all of the template packages. In this case all of the projects must have the same version set
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- LanguageExt.Core (>= 4.4.8)
- MediatR (>= 12.2.0)
- OneOf (>= 3.0.263)
- OneOf.SourceGenerator (>= 3.0.263)
- WebApiSkeleton.Contracts.Base (>= 1.1.1)
- WebApiSkeleton.Contracts.Validation (>= 1.1.1)
- WebApiSkeleton.Security.Core (>= 1.1.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.