Tag - .NET-7

GitHub CI/CD Tutorial for Pipelines
Jan 12, 2024

In this blog, I will guide you on the power of CI/CD in GitHub with a step-by-step guide. Learn to set up automated workflows, boost project efficiency, and streamline development processes for better code quality and faster deployments. Certainly! It seems that I've encountered a challenge in my current development workflow when deploying minor code changes. The existing process involves manually publishing code from Visual Studio, creating backups of the current code on the server, and then replacing it with the new code. To address this, it's advisable to transition to an automated solution utilizing a Continuous Integration/Continuous Deployment (CI/CD) pipeline.  By implementing a CI/CD pipeline, you can streamline and automate the deployment process, making it more efficient and reducing the risk of manual errors. The CI/CD pipeline will handle tasks such as code compilation, testing, and deployment automatically, ensuring that the latest changes are seamlessly deployed to the desired environment.  This transition will not only save time but also enhance the reliability of your deployment process, allowing your team to focus more on development and less on manual deployment tasks.  For additional information, refer to the steps outlined below for guidance.   Step 1:  Go to your repository and click on the Actions tab   Step 2:  Now, Select the workflow according to your development. Here I am using .NET workflow.   Step 3:  Now you can see the default pipeline as below. In that, you can change your branch as per your requirement. Step 4:  You can now incorporate three new sections as outlined below to build the code and publish the folder as an artifact.  - name: Build and publish      run: |        dotnet restore        dotnet build        dotnet publish -o publish    - name: Zip output      run: |        cd publish        zip -r ../output .  - name: Upload zip archive      uses: actions/upload-artifact@v2      with:        name: test        path: ./publish  Upon integrating this code, your YAML file will now appear as follows.  In the code above, you have the flexibility to rename the zip file or the publish folder according to your preferences.  Build and Publish : This step is responsible for building and publishing the code.  Commands:  dotnet restore: Restores the project's dependencies.  dotnet build: Compiles the project.  dotnet publish -o publish: Publishes the project output to the 'publish' folder.    Zip Output : This step involves compressing the contents of the 'publish' folder into a zip file.  Commands:  cd publish: Changes the working directory to the 'publish' folder.  zip -r ../output .: Creates a zip file named 'output' containing the contents of the 'publish' folder.    Upload Zip Archive :This step uploads the zip archive to the workflow run as an artifact.  Using: The actions/upload-artifact@v2 GitHub Action.  Configuration:  name: test: Specifies the name of the artifact as 'test'.  path: ./publish: Indicates the path of the folder to be archived and uploaded.  By using the given code, you receive a finalized published folder prepared for deployment on the server. However, the deployment process on the server requires manual intervention.  To access the published folder, navigate to the "Actions" tab. Click on the "test" workflow, and you can download the published folder from there.  Step 5:  In the steps mentioned above, you previously followed a manual process, but now you have transitioned to an automatic process.  To automate the process, you'll need to install a self-hosted runner on the virtual machine where your application is hosted.  What is Self-hosted runner?  self-hosted runner is a system that you deploy and manage to execute jobs from GitHub Actions on GitHub.com.  To install the self-hosted runner, follow the basic steps.  Under your repository name, click Settings. If you cannot see the "Settings" tab, select the dropdown menu, then click Settings. In the left sidebar, click Actions, then click Runners and then click on New self-hosted runner.  Select the operating system image and architecture of your self-hosted runner machine.  Open a shell on your self-hosted runner machine and run each shell command in the order shown. For more details you can visit https://docs.github.com/en/enterprise-cloud@latest/actions/hosting-your-own-runners/managing-self-hosted-runners/adding-self-hosted-runners  Step 6:  To automate the process, you can remove the last two sections, "Zip Output" and "Upload Zip Archive," and replace them with the following code.  - name: Backup & Deploy      run: |        $datestamp = Get-Date -Format "yyyyMMddHHmmss"        cd publish        Remove-Item web.config        Remove-Item appsettings.json        Remove-Item appsettings.Development.json        Stop-WebSite 'DemoGitHubPipeline'        Compress-Archive D:\Published\DemoGitHubPipeline         D:\Published\Backup\Backup_$datestamp.zip        Copy-Item * D:\Published\DemoGitHubPipeline -Recurse -Force        Start-WebSite 'DemoGitHubPipeline'  Backup & Deploy : This step is responsible for creating a backup, making necessary modifications, and deploying the application. Commands:  $datestamp = Get-Date -Format "yyyyMMddHHmmss": Retrieves the current date and time in the specified format.  cd publish: Changes the working directory to the 'publish' folder.  Remove-Item web.config: Deletes the 'web.config' file.  Remove-Item appsettings.json: Deletes the 'appsettings.json' file.  Remove-Item appsettings.Development.json: Deletes the 'appsettings.Development.json' file.  Stop-WebSite 'DemoGitHubPipeline': Stops the website with the specified name.  Compress-Archive D:\Published\DemoGitHubPipeline D:\Published\Backup\Backup_$datestamp.zip: Creates a compressed archive (zip) of the existing deployment with proper timestamp.  Copy-Item * D:\Published\DemoGitHubPipeline -Recurse -Force: Copies all contents from the 'publish' folder to the deployment directory.  Start-WebSite 'DemoGitHubPipeline': Restarts the website with the specified name.    Note:  Ensure that the paths and folder structures match the actual locations in your setup.  Adjust the website name and paths based on your specific configuration.  Conclusion: In summary, implementing a CI/CD pipeline in GitHub is a pivotal step towards achieving efficiency, reliability, and accelerated development cycles. The integration of CI/CD streamlines the software delivery process by automating testing, building, and deployment, leading to consistent and high-quality releases.  GitHub Actions, with its native CI/CD capabilities, provides a powerful and flexible platform for orchestrating workflows. Leveraging its features, development teams can not only automate repetitive tasks but also ensure rapid feedback on code changes, enabling early detection of issues and facilitating collaboration. 

Quick Tips: Managing Expired Tokens
Jan 01, 2024

Here, I will explain how to restrict users from using expired tokens in a .NET Core application. Token expiration checks are crucial for ensuring the security of your application.   Here's a general outline of how you can achieve this: 1. Configure Token Expiration: When generating a token, such as a JWT, set an expiration time for the token. This is typically done during token creation. For example, when using JWTs, you can specify the expiration claim:   var tokenDescriptor = new SecurityTokenDescriptor {     Expires = DateTime.Now.AddMinutes(30) // Set expiration time }; 2. Token Validation Middleware: Create middleware in your application to validate the token on each request. This middleware should verify the token's expiration time. You can configure this middleware in the startup or program file on the .NET side.   public void Configure(IApplicationBuilder app, IHostingEnvironment env) {     app.UseMiddleware<TokenExpirationMiddleware>(); } 3. Token Expiration Middleware: Develop middleware to validate the token's expiration time. Take note of the following points: ValidateIssuerSigningKey: Set to true, indicating that the system should validate the issuer signing key. IssuerSigningKey: The byte array represents the secret key used for both signing and verifying the JWT token. ValidateIssuer and ValidateAudience: Set to false, indicating that validation of the issuer and audience is skipped. By setting ClockSkew to TimeSpan.Zero, you specify no tolerance for clock differences. If the current time on the server or client is not precisely within the token's validity period, the token is considered expired.      public class TokenExpirationMiddleware     {         private readonly RequestDelegate _next;         public TokenExpirationMiddleware(RequestDelegate next)         {             _next = next;         }         public async Task Invoke(HttpContext context)         {             // Check if the request has a valid token             var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();             if (token != null)             {                 var tokenHandler = new JwtSecurityTokenHandler();                 var key = Encoding.ASCII.GetBytes("YourSecretKey"); // Replace with your actual secret key of Issuer                 var tokenValidationParameters = new TokenValidationParameters                 {                     ValidateIssuerSigningKey = true,                     IssuerSigningKey = new SymmetricSecurityKey(key),                     ValidateIssuer = false,                     ValidateAudience = false,                     ClockSkew = TimeSpan.Zero                 };                 try                 {                     // Validate the token                     var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out var securityToken);                     // Check if the token is expired                     if (securityToken is JwtSecurityToken jwtSecurityToken)                     {                         if (jwtSecurityToken.ValidTo < DateTime.Now)                         {                             // Token is expired                             context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                             return;                         }                     }                 }                 catch (SecurityTokenException)                 {                     // Token validation failed                     context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;                     return;                 }             }             await _next(context);         }     } Working fine with proper token time. Here is an example: I am providing an expired token, and it will result in a 401 Unauthorized status. You can also check the token in https://jwt.io/ for time expired (exp) . By following these steps, you can effectively implement checks to ensure that users are not able to use expired tokens within your .NET Core application.

magnusminds website loader