110 Security: Preparing application to run - chempkovsky/CS82ANGULAR GitHub Wiki

Two aspects

Security has two aspects: Authentication and Authorization

Notes

  • Reminder: Middleware order
  • Two additional database contexts have been added to the application.
    • It requires configuration of the Connection Strings and Dbcontexts.
  • Everything is ready to enable security
    • It requires configuration Authentication and Authorization at the server side
    • It requires configuration Authentication and Authorization at the client side

Steps required to accomplish the task

Set up PhBkWebApp

appsettings json for PhBkWebApp

  • open the appsettings.json-file and add two Connection Strings
    • "AuthConnection"
    • "AspNetRegConnection"
  "ConnectionStrings": {
    "PhBkConnection": "Data Source=SVR2016SQL2017;Initial Catalog=PhBkDbDef;Persist Security Info=True;User ID=sa;Password=Qq01011967",
    "AuthConnection": "Data Source=SVR2016SQL2017;Initial Catalog=PhBkDbAuth;Persist Security Info=True;User ID=sa;Password=Qq01011967",
    "AspNetRegConnection": "Data Source=SVR2016SQL2017;Initial Catalog=PhBkAspNet;Persist Security Info=True;User ID=sa;Password=Qq01011967"
  }
  • Jwt-Authentication needs to be configured as well
    • add Jwt-section to the appsettings.json-file
  "JWT": {
    "ValidAudience": "PhBkAudience",
    "ValidIssuer": "PhBkIssuer",
    "Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr"
  }

Program file for PhBkWebApp

  • open Program.cs-file
  • Add configuration of aspnetchckdbcontext-context
var builder = WebApplication.CreateBuilder(args);

ConfigurationManager configuration = builder.Configuration;
...

builder.Services.AddDbContext<aspnetchckdbcontext>(options =>
    options.UseSqlServer(configuration.GetConnectionString("AuthConnection")));
  • Add configuration of Jwt-Authentication
    • it includes configuration of AspNetRegistrationDbContext-Dbbcontext
var builder = WebApplication.CreateBuilder(args);

ConfigurationManager configuration = builder.Configuration;
...
#region authentification
builder.Services.AddDbContext<AspNetRegistrationDbContext>(options =>
    options.UseSqlServer(configuration.GetConnectionString("AspNetRegConnection")));
builder.Services.AddIdentity<IdentityUser, IdentityRole>()
    .AddEntityFrameworkStores<AspNetRegistrationDbContext>().AddDefaultTokenProviders();
builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.SaveToken = true;
    options.RequireHttpsMetadata = true;
    options.TokenValidationParameters = new TokenValidationParameters() {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidAudience = configuration["JWT:ValidAudience"],
        ValidIssuer = configuration["JWT:ValidIssuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWT:Secret"]))
    };
});
builder.Services.AddHttpContextAccessor();
  • turn ON Authentication and Authorization
...
var app = builder.Build();
...
app.UseAuthentication();
app.UseAuthorization();

Set up LpPhBkWebApp

appsettings json for LpPhBkWebApp

  • open appsettings.json-file and add THE SAME Jwt-section.
    • PhBkWebApp will function as OAuth server
    • LpPhBkWebApp will function as OAuth client
  "JWT": {
    "ValidAudience": "PhBkAudience",
    "ValidIssuer": "PhBkIssuer",
    "Secret": "JWTAuthenticationHIGHsecuredPasswordVVVp1OH7Xzyr"
  }

Program file for LpPhBkWebApp

  • Open Program.cs-file of the LpPhBkWebApp-project and add THE SAME code for Jwt-Authentication
    • Note: We do not need AspNetRegistrationDbContext
#region authentification
builder.Services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options => {
    options.SaveToken = true;
    options.RequireHttpsMetadata = true;
    options.TokenValidationParameters = new TokenValidationParameters() {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidAudience = configuration["JWT:ValidAudience"],
        ValidIssuer = configuration["JWT:ValidIssuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWT:Secret"]))
    };
});
builder.Services.AddHttpContextAccessor();
#endregion
  • turn ON Authentication and Authorization
...
var app = builder.Build();
...
app.UseAuthentication();
app.UseAuthorization();

Set up Angular App

appConfig json

  • open src\assets\app-config.json and modify
    • "securityUrl"
    • "permissionWebApi"
{
  "webApiUrl": "http://localhost:5165/",
  "securityUrl": "http://localhost:5165/",
  "permissionWebApi": "http://localhost:5165/",
  "divisionLpWebApi": "http://localhost:5055/",
  "employeeLpWebApi": "http://localhost:5055/",
  "phoneLpWebApi": "http://localhost:5055/"
}

AppGlblSettingsService

  • open src\app\shared\services\app-glbl-settings.service.ts and modify
    • getViewModelMask-method
    • getDashBrdMask-method
    getViewModelMask(vwModel: string): number {
      //return 31; // delete this line when vwModels is ready
      let pk = this.vwModels[vwModel];
      if(typeof pk === 'undefined') { return 0; } else { return pk; }
    }
    getDashBrdMask(dshBrd: string): number {
      //return 1; // delete this line when dshBrds is ready
      let pk = this.vwModels[dshBrd];
      if(typeof pk === 'undefined') { return 0; } else { return pk; }
    }

accountcontroller

  • open accountcontroller.cs-file and take a look at the Register()-method
        [HttpPost]
        [Route("api/[controller]/register")]
        public async Task<IActionResult> Register([FromBody] registerbindingmodel model)
        {
            await CreateAdminAndGuest();
            ...
        } 

Role base Authorization

  • any method of any WebApi controller you can protect using Authorize-attribute
    • it will work for both apps: PhBkWebApp and LpPhBkWebApp
  • open accountcontroller.cs-file and take a look at the Login()-method
    • it puts all the roles of the current user in the token
      • this way all user roles will be available to the LpPhBkWebApp-application
        [HttpPost]
        [Route("token")]
        public async Task<IActionResult> Login([FromBody] loginbindingmodel model)
        {
            var user = await _userManager.FindByNameAsync(model.UserName);
            if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
            {
                var userRoles = await _userManager.GetRolesAsync(user);

                var authClaims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                };

                foreach (var userRole in userRoles)
                {
                    authClaims.Add(new Claim(ClaimTypes.Role, userRole));
                }

                var token = GetToken(authClaims);

                return Ok(new
                {
                    token_type = "Bearer",
                    user_name = model.UserName,
                    access_token = new JwtSecurityTokenHandler().WriteToken(token),
                    expiration = token.ValidTo
                });
            }
            return Unauthorized();
        }
⚠️ **GitHub.com Fallback** ⚠️