Admin

Himanshu Pranami

I'm working as a Software Developer at MagnusMinds IT Solution. I bring 3+ years of professional experience to the table. My expertise spans a range of technologies, including .NET Framework, .NET Core, MVC, ASP.NET, Entity Framework, ADO.NET, SQL, PostgreSQL, C#, Azure DevOps, and Microservices.

Posts by Himanshu Pranami

API Fixed response
Feb 03, 2024

Simplifying API Responses with AutoWrapper.Core in .NET Core. Handling API responses effectively is a crucial aspect of building robust and user-friendly applications. In .NET Core applications, the AutoWrapper.Core library comes to the rescue, providing a streamlined way to structure and standardize API responses. In this blog post, we'll explore how to use AutoWrapper.Core to create fixed responses for different status codes in your API. Firstly, you'll need to install the AutoWrapper.Core NuGet package. Add the following line to your project's .csproj file: <PackageReference Include="AutoWrapper.Core" Version="4.5.1" /> This package simplifies the process of handling API responses and ensures a consistent format for success, error, and data messages.   Example: Login Method Let's consider a common scenario, the login method, where we want to ensure fixed responses for both successful and unsuccessful attempts. [HttpPost("Login")] public async Task<ApiResponse> Login([FromBody] Login model) { var user = await _userService.GetUserByName(model.UserName); if (user != null && await _userService.CheckUserPassword(user, model.Password)) { var userResponse = await _tokenService.GenerateToken(user); return new ApiResponse(message: "Login Successfully.", result: userResponse, statusCode: 200); } return new ApiResponse(message: "Invalid Credential.", result: null, statusCode: 401); } In this example, we're using AutoWrapper.Core's ApiResponse class to encapsulate our responses. For a successful login attempt (status code 200), we return a positive message along with the user response. In case of invalid credentials (status code 401), an appropriate error message is provided. ApiResponse Class Now, let's take a closer look at the ApiResponse class from AutoWrapper.Core: namespace AutoWrapper.Wrappers; public class ApiResponse { public string Version { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public int StatusCode { get; set; } public string Message { get; set; } [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? IsError { get; set; } public object ResponseException { get; set; } public object Result { get; set; } [JsonConstructor] public ApiResponse(string message, object result = null, int statusCode = 200, string apiVersion = "1.0.0.0") { StatusCode = statusCode; Message = message; Result = result; Version = apiVersion; } public ApiResponse(object result, int statusCode = 200) { StatusCode = statusCode; Result = result; } public ApiResponse(int statusCode, object apiError) { StatusCode = statusCode; ResponseException = apiError; IsError = true; } public ApiResponse() { } } The ApiResponse class provides flexibility in constructing responses with different components such as the message, result, and status code. It helps maintain a standardized format for all API responses. Create a Custom Wrapper: AutoWrapper allows you to create a custom wrapper by implementing the IApiResponse interface. You can create a class that implements this interface to customize the fixed response. Here's an example: Create a Custom Wrapper: AutoWrapper allows you to create a custom wrapper by implementing the IApiResponse interface. You can create a class that implements this interface to customize the fixed response. Here's an example: using AutoWrapper.Wrappers; public class CustomApiResponse<T> : ApiResponse<T> { public string CustomProperty { get; set; } public CustomApiResponse(T result, string customProperty) : base(result) { CustomProperty = customProperty; } } Configure AutoWrapper: In your Startup.cs file, configure AutoWrapper to use your custom wrapper. You can do this in the ConfigureServices method: services.AddAutoWrapper(config => { config.UseCustomSchema<CustomApiResponse<object>>(); }); Replace CustomApiResponse<object> with the custom wrapper class you created. Use Custom Wrapper in Controller Actions: Now, you can use your custom wrapper in your controller actions. For example: [ApiController] [Route("api/[controller]")] public class MyController : ControllerBase { [HttpGet] public IActionResult Get() { // Your logic here var data = new { Message = "Hello, World!" }; // Use the custom wrapper var response = new CustomApiResponse<object>(data, "CustomProperty"); return Ok(response); } } Customize the CustomApiResponse according to your needs, and use it in your controller actions. This way, you can integrate AutoWrapper with other packages and customize the fixed response format in your .NET application.   In conclusion, by incorporating AutoWrapper.Core into your .NET Core applications, you can simplify the handling of API responses, making your code more readable, maintainable, and user-friendly. Consider adopting this approach to enhance the overall developer experience and ensure consistency in your API communication.

How to Configure AWS Cognito for Login Flow
Jan 31, 2024

  To set up the AWS Cognito for the registration/login flow, follow these steps: First Flow: User Registration in Cognito1. Install the following NuGet packages in your .NET project:   <PackageReference Include="Amazon.AspNetCore.Identity.Cognito" Version="3.0.1" /> <PackageReference Include="Amazon.Extensions.Configuration.SystemsManager" Version="5.0.0" /> <PackageReference Include="AWSSDK.SecretsManager" Version="3.7.101.27" /> Declare AWS configuration values in appsettings: "Region": "me-south-1", "UserPoolClientId": "UserPoolClientId", "UserPoolClientSecret": "UserPoolClientSecret", "UserPoolId": "me-south-pool"   Additional Configuration Add authentication in program/startup files to enable sign-in with Cognito. 2. Create a CognitoUserPool with a unique ID in the controller: private readonly CognitoUserPool _pool; private readonly CognitoUserManager<CognitoUser> _userManager; var user = _pool.GetUser(registerUserRequest.LoginId); 3.Add user attributes (email, phone number, custom attributes) using user.Attributes.Add().   user.Attributes.Add(CognitoAttribute.Email.AttributeName, registerUserRequest.Email); user.Attributes.Add(CognitoAttribute.PhoneNumber.AttributeName, registerUserRequest.Mobile); user.Attributes.Add("custom:branch_code", registerUserRequest.BranchCode); user.Attributes.Add("custom:preferred_mode", preferedMode); 4. Create the user: cognitoResponse = await _userManager.CreateAsync(user, registerUserRequest.Password); Check cognitoResponse.Succeeded to determine if the user was created successfully.   Second Flow: User Login with Cognito 1.Search for the user in Cognito using the login ID: var cognitoUser = await _userManager.FindByIdAsync(loginUserRequest.LoginId);   2.Set a password for the Cognito model: var authRequest = new InitiateSrpAuthRequest {    Password = loginUserRequest.Password };   3.Use StartWithSrpAuthAsync to get the session ID: var authResponse = await cognitoUser.StartWithSrpAuthAsync(authRequest);   4.Add MFA method and validate using MFA auth if needed. For MFA validation, set the MFA settings in Cognito:v ar authRequest = new RespondToMfaRequest {        SessionID = validateLoginUserRequest.SessionId,        MfaCode = validateLoginUserRequest.Otp,        ChallengeNameType = ChallengeNameType.SMS_MFA }; authResponse = await cognitoUser.RespondToMfaAuthAsync(authRequest);   Extract tokens from Cognito: authResponse.AuthenticationResult.IdToken authResponse.AuthenticationResult.RefreshToken   Forgot Password Flow 1.Search for the user with LoginId in Cognito and call ForgotPasswordAsync: var user = await _userManager.FindByIdAsync(loginUserRequest.LoginId); await user.ForgotPasswordAsync();   2.Optionally, call ConfirmForgotPassword method in Cognito. _userManager.ConfirmForgotPassword(userID, token, newPassword, CancellationToken cancellationToken) Here, understanding AWS Cognito Authentication Methods and Utilizing Them as Needed.  

Host the Angular Application to IIS
Jan 23, 2024

Hosting an Angular application on IIS involves a few straightforward steps.    Follow this step-by-step guide to seamlessly deploy your Angular project on IIS. Step 1: Open Your Angular Project in Visual Studio Code Review the build command in the package.json file. By default, it's usually set to ng build. Step 2: Run the Build Command Execute the ng build command in the terminal to compile your Angular application.  This command creates a 'dist' folder, typically located at the specified output path in the angular.json file. Step 3: Install IIS Ensure that IIS is installed on your machine. You can install it through the "Turn Windows features on or off" option in the Control Panel. Step 4: Create a New Site in IIS Open the IIS Manager. In the Connections pane, right-click on the "Sites" node and select "Add Website." Fill in the required information, such as the Site name, Physical path to the folder , and choose a port. Step 5: Configure URL Rewrite (Optional) If your Angular application uses routing, consider configuring URL Rewrite for proper routing.  Create a 'web.config' file in your 'dist' folder with the appropriate configurations. Here's a simple example of a web.config file for an Angular application with routing.This file helps configure how the server handles URL requests. ---------------------------------------------------------------------------------------------------------------- <?xml version="1.0" encoding="utf-8"?> <configuration>   <system.webServer>     <rewrite>       <rules>         <rule name="Angular Routes" stopProcessing="true">           <match url=".*" />           <conditions logicalGrouping="MatchAll">             <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />             <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />           </conditions>           <action type="Rewrite" url="/" />         </rule>       </rules>     </rewrite>     <staticContent>       <remove fileExtension=".json" />       <mimeMap fileExtension=".json" mimeType="application/json" />     </staticContent>   </system.webServer> </configuration> ---------------------------------------------------------------------------------------------------------------- Step 6: Restart IIS After making these changes, restart IIS to apply the configurations. Step 7: Access Your Angular Application Open a web browser and navigate to http://localhost:yourport (replace 'yourport' with the specified port from Step 4). Now, your Angular application is hosted on IIS. Access it through the specified port. If any issues arise, check the IIS logs for more information.  Customize these instructions based on your specific requirements and environment. Thanks!

Mastering API Security: A Guide to Conditional Authorization and Swagger Customization
Jan 02, 2024

In this blog, I will be sharing insights on how to effectively manage Conditional Authorization and Swagger Customization.   Case 1   I'm currently working on a problem our QA team found while testing our website. Specifically, there's an issue with one of the features in the application that uses an API. In the QA environment, we need to allow access without authentication, but in the production environment, authentication is required. To fix this, I added a feature called Conditional Authorize Attribute with help of Environment Variable. This feature lets us control access to the API based on the environment. It allows anonymous access when necessary.   In my situation, I've added a environment variable setting called "ASPNETCORE_ENVIRONMENT" to "QA" in the testing site's pipeline. Because of this, I can use the API on the QA server without requiring authentication.   This method also helps specific authorization rules for the API based on the environment.   Case 2 Additionally, I've added Swagger requests into a value object to meet specific requirements on swagger. By extending the Swashbuckle Swagger IOperationFilter, I integrated logic tailored to our needs. This approach allows us to customize requests in Swagger for all APIs directly.   Furthermore, I've implemented a middleware designed to handle responses and here's how it works. In my case, there are three kinds of response class in my code that specify the response type (like ApiErrorResponse, ValidatorResponse, ResponseModel). According to the requirements, when we get a 200-status code with the correct response class model, I need to wrap the response object in a value format. I created a middleware for this. It figures out which endpoint we're dealing with through the HttpContext. Using that endpoint, I grab the metadata related to the ProducesResponseTypeAttribute class and check for a status code of OK (Metadata Extraction). If I manage to get the metadata with a status code of 200, I include that response in value format. Otherwise, I stick with the same model response. This helps you to modify the response as per needed outcome. These implementations provide a flexible solution for conditionally authorizing API access and wrapping request/response in an object according to specified requirements.

Restrict user to use Expired token
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.