This project is a series of Proofs of Concept (POCs) that implements comprehensive web security measures using the .NET framework. Starting with basic authentication methods like Cookie based authentication and JWT authentication, then explores multiple authentication schemes in .Net. Applies Permission-based access control. And implements OAuth/OpenIdConnect for authentication and authorization.
- This project uses .Net 6.
 - Each project has its own section for explaning its purpose and what have been used in it, and what was used as external libraries.
 - If you want to run a project, then check its details section if it uses a DB and if so, make sure to apply migrations before running the project.
 - For 
OAuthandOpenIdConnectprojects, you have to provide your own the ClientId and ClientSecret for your registered applications. - For 
OAuthandOpenIdConnectprojects, don't try to start the flow by hitting the dedicated endpoints using Swagger endpoints you will hit error, instead open a tab and specify the full path for the endpoints. 
- 
Implements Cookie-based authentication in .Net.
 - 
No External DB connection was used, only a set of fake users in memory in
AuthenticationServiceto mimic the authentication process. - 
Exploits the built-in functionality in .Net to achieve such an authentication measure, no external libraries were used.
 - 
If the user exists in the system we assign him claims such as [Name, Id, and Role], and signs him in with the
Cookiesauthentication scheme. - 
Exposes
/loginand/logoutendpoints inHomeController, Implements simple role-based access control on some resources inWeatherForecastControllerto validate the functionality of cookie authentication. 
- 
Implements JWT authentication in .Net.
 - 
Uses
Microsoft.AspNetCore.Authentication.JwtBearerlibrary for implementing the JWT authentication process in .Net. - 
Uses MS SQL Server as a database to implement simple user model functionality. Stores hashed passwords.
 - 
Exposes
/Signinand/Signoutendpoints inHomeController. - 
Implements the JWT generation in
AuthenticationServicewhich is done by signing the current user with simple claims such [Sub, Email, and Jti]. - 
Protects the endpoint in the
WeatherForecastControllerso it requires to be authenticated before accessing the resource. - 
Implements
UserDataMiddlewarewhich is executed immediately after the built-inAuthenticationMiddlewareto retrieve the user model from DB and stroe it in the request context by by extracting his Id from claims. 
- 
Implements 2 Cookie-based authentication schemes, one is dedicated for
regularusers and the other forspecialusers - 
No External DB connection was used, only a set of fake users in memory in
AuthenticationServiceto mimic the authentication process. - 
Exposes
/login-regular,/logout-regularfor regular users and/login-special,/logout-specialfor special users inHomeController - 
A user can authenticate himself with both endpoints; and he will get the corresponding role
regularorspecialas well. - 
Overrides the
AuthorizationPolicyBuilderbehavior inPoliciesExtensionsto accept authenticated users from both schemes instead of the default one only. - 
Defines
OnlySpecialUsersauthorization policy which only authorizes special users to access the resources decorated with this policy. - 
Validates the functionality of muliple authentication schemes in
WeatherForecastControllerby defining an accessible resource by both schemes, and by defining a dedicated resource only for special users using the above mentioned policy. 
- 
Implements session-based authentication from scratch by introducing new custom session-based authentication scheme and its corresponding authentication handler.
 - 
No External DB connection was used, only a set of fake users and roles implemented in-memory in
InMemoryUserService. - 
An in-memory session manager implementation for managing user's session resides in
InMemorySessionManager. Provides several functionalities such session Creation, Retrieving, and Revoking sessions. - 
Exposes
/sign-inand/sign-outendpoints for users authentication inHomeController - 
As mentioned previously, this project introduces new authentication scheme and its corresponding handler by:
- Introducing 
SessionAuthenticationOptionsto customize the configuration and functionality of the implementation. - Introducing 
SessionAuthenticationHandlerwhich handles the following functionalities:- Implements 
HandleSignInAsyncmethod which creates a new user session and writes the session identifier to cookies, - Implements 
HandleSignOutAsyncmethod which reads the session from the cookies and revoke it, then it clears the cookies from that session. - Implements 
HandleAuthenticateAsyncmethod which returns an AuthenticationResult representing the validity of the session. That's done by checking if the session is not revoked nor expired. After that if everything is validated, then we append a ClaimsPrinciple to the AuthenticationResult instance representing the user's context to be used later for authroization in the application. This method is called by built-inAuthenticationMiddleware 
 - Implements 
 - Registering the custom session-based authentication handler as our default authentication scheme in our application, that's done by using the methods provided by 
SessionExtensionsto register our scheme. It's been done inAuthExtensions 
 - Introducing 
 - 
HomeControllerusesAuthenticationServiceinternally which in turn specifies our new custom scheme to sign in and sign out users. - 
WeatherForecastControllerintroduces endpoints and authorizes access to some of them based on the user's roles, which got evaluated and populated to request context inSessionAuthenticationHandler. This proves the correctness of our custom scheme implementation. 
- 
Implements permission-based access control, and uses Jwt for authentication
 - 
Uses MS SQL Server as a database to implement the mentioned relationship.
 - 
The following relationship between entities is implemented where:
Userrepresents the users in the system.Roleare system rolesPermissionare system permissionsUserRoleandRolePermissionare junction tables to represent m-m relationships between entities.
 
- 
Exposes
/loginand/sign-upendpoints inUserControllerto authenticate and register users. - 
Once the user is authenticated, he will receive a JWT token containing all his permissions for the system. That's managed by
UserService - 
The process of authorizaing users and determining their access level is implemented by exploiting the .Net built-in policy-based authorization and by overriding some of the built-in .Net identity features and introducing some attributes and helpers such:
- Introducing 
PermissionRequirementclass which will hold the permission name dedicated for a specific resource - Introducing 
PermissionAuthorizationHandlerwhich handles and determines if the user is authorized to access a resource by extracing his permissions from his Jwt token. - Overriding 
DefaultAuthorizationPolicyProviderbehavior inPermissionPolicyProviderand registering it as the default one in the project. So if our policies start with the special prefix "CustomPermission:" then we build a policy at run time and inject to it PermissionRequirement - Introducing 
HasPermissionAttributeclass which handles the abstraction of adding the special prefix to each permission. - Now the developers can use the 
HasPermissionattribute, and pass to it the permission name the user should have to access the resource. 
 - Introducing 
 - 
The flow for of how the system will work when a user tries to access an endpoint decorated with
HasPermissionattribute:- The .Net built-in 
AuthorizationServicewill extract the permission name from theHasPermission, which represents a policy name - The overridden 
PermissionPolicyProviderwill detect that this permission starts with the pre-defined special prefix and will build a policy at run time containingPermissionRequirementrequirement - After getting the policy built at run time, the 
AuthorizationServicewill evaluate this policy by invoking the requirement's authorization handler which isPermissionAuthorizationHandler, and it will check if there is a permission in user's jwt matches the one specified atHasPermissionattribute. 
 - The .Net built-in 
 - 
ProductController,ItemControllerand their respective services and entities were introduced as resources so authorized users can manipulate them. This also provides a way to check the correctness of the implementation. - 
PermissionControlleris introduced to provide admins the ability to manipulate permissions, roles, and managing other users' permissions dynamically. 
- 
Implements OAuth flow for granting the application access to third-part applications.
 - 
The application authenticates users and serves them without storing any kind of users' information in its own system, so no Database was used at all.
 - 
The application does not use any external libraries but the .Net built-in implementation for OAuth.
 - 
The third-party application in this project was
GitHub. In this project, we try to access user's repositories from GitHub. - 
User secrets feature in .Net was used to store ClientId and ClientSecret for the GitHub registered application, so if you want to run this project, you need to provide yours.
 - 
The application requests only one scope
repo, which grant the application access to all the user's repositories. - 
These are the following third-party (GitHub) endpoints provided for the OAuth flow:
- Authorization endpoint: 
https://github.com/login/oauth/authorize - Token endpoint: 
https://github.com/login/oauth/access_token - User info endpoint: 
https://api.github.com/user 
 - Authorization endpoint: 
 - 
The application flow of OAuth flow as follows:
- User starts the OAuth flow by the hitting the exposed 
/login/githubendpoint inHomeController, so the application can request an access to the user account from GitHub. - Upon user consent for the application to access the scopes the application requested, the application gets an authorization code to exchange it for access token later.
 - The application gets an access token after exchanging the authorization code and it stores it in the user's context, specifically in 
AuthorizationProperties. - The application uses .Net 
Cookiesauthentication for creating user context upon successful OAuth flow. 
 - User starts the OAuth flow by the hitting the exposed 
 - 
Don't try to start the flow by hitting
/login/githubusing Swagger endpoint you will hit error, instead open a tab and specify the full path for the endpoints. - 
Upon successful OAuth flow, the user can use the endpoints provided by
UserControllerwhich internally usesGithubUserService:/github/meendpoint to get user's GitHub profile information. That's done by hitting a request to the User info endpoint mentioned above using the granted access token./github/repositories/meendpoint to list all the user's GitHub repositories; and for sure, that's done through passing the previously granted access token tohttps://api.github.com/users/{username}/reposendpoint.
 
- 
Implements OpenIdConnect flow for authenticating/logging users with external providers.
 - 
The external providers the application integrates with are
GoogleandGitHub. - 
User secrets feature in .Net was used to store ClientId and ClientSecret for both Google and GitHub registered application, so if you want to run this project, you need to provide yours.
 - 
It's important to mention that
GitHubdoes not implement OpenIdConnect protocol, so to get the identity of the user we have to manually hit the user info endpoint to get his identity information. - 
This POC project does not only implement OIDC but also extends further the scope to try and manage its own data by storing authenticated users in its own DB and assigning users roels which are also managed by the system.
 - 
Googledoes implement OpenIdConnect protocol, so upon successful exchange for the authroization code, we will get an ID token which will contain the user's identity information; also it provides user info endpoint for more details about the user. - 
Microsoft.AspNetCore.Authentication.OpenIdConnectwas used for integrating withGooglewhile built-in .Net OAuth implementation was used forGitHub. - 
The endpoints provided by external providers:
- Google:
- Authorization endpoint: 
https://accounts.google.com/o/oauth2/v2/auth - Token endpoint: 
https://oauth2.googleapis.com/token - User info endpoint: 
https://openidconnect.googleapis.com/v1/userinfo 
 - Authorization endpoint: 
 - GitHuib:
- Authorization endpoint: 
https://github.com/login/oauth/authorize - Token endpoint: 
https://github.com/login/oauth/access_token - User info endpoint: 
https://api.github.com/user 
 - Authorization endpoint: 
 
 - Google:
 - 
The following relationship between entities is implemented where:
Userrepresents the system users.Rolerepresents the system roles.ExternalLoginrepresents the login by external providers, e.g Google, GitHub. The relationship withUseris 1-m.ExternalLoginRolerepresents a junction table to link each external login with its roles.
 
- 
Uses MS SQL Server as a database to implement the mentioned relationship.
 - 
The flow of Google OIDC as follows:
- User starts the OIDC flow by hitting the exposed 
/login/googleendpoint inHomeController, so the application can request an access to the user account from Google. - Internally the used library append 
openidscope to the scopes going to be request from Google authorization server. - Upon user consent for the application to access the scopes the application requested, the application gets an authorization code to exchange it for access and ID tokens later.
 - The application gets access and Id tokens after exchanging the authorization code, extracts user information and stores them in the user's context, specifically in 
AuthorizationProperties. - The system ensures the user created and stored in the its own DB.
 - The system assigns the user's roles and append them to the context.
 - The application uses .Net 
Cookiesauthentication for creating user context upon successful OIDC flow. 
 - User starts the OIDC flow by hitting the exposed 
 - 
The flow of GitHub OAuth used for authentication as follows:
- User starts the OAuth flow by the exposes 
/login/githubendpoint inHomeController, so the application can request an access to the user account from GitHub. - Upon user consent for the application to access the scopes the application requested, the application gets an authorization code to exchange it for access token later.
 - The application gets an access token after exchanging the authorization code and it stores it in the user's context, specifically in 
AuthorizationProperties. - The application uses the granted access token to hit 
https://api.github.com/userto get user info and extracts properties and stores them in user's context also. - The system ensures the user created and stored in the its own DB.
 - The system assigns the user's roles and append them to the context.
 - The application uses .Net 
Cookiesauthentication for creating user context upon successful OAuth flow. 
 - User starts the OAuth flow by the exposes 
 - 
Don't try to start the flow by hitting
/login/githubor/login/googleusing Swagger endpoint you will hit error, instead open a tab and specify the full path for the endpoints. - 
The custom logic for storing users in the system's DB and managing roles is achieved through exploiting the provided Events in OAuth/OIDC .Net implementations.
 - 
ResourceControllerexposes endpoints with different access levels depending on the user's roles, this is to ensure and validate the correctness of the implementation. 

