How to connect your Web API BackOffice ?

Estimated reading: 3 minutes 84 views

Requirement

You need to have already

  • VGIdentityServer installed in your environment.
  • Front application use VGIdentityServer

Definition

  • VGIdentityServerUrl: Url of the VG Identity Server
  • WebAPIUrl: Url of your MVC API BackOffice
  • VGClientId: The id of the your config inside of your VGApplication
  • VGClientSecret: The secret key inside of your VGApplication

Connect your application to VGIdentityServer

You need to open Visual-Studio and select your project

You need to add the Nuget packages to your project

  • IdentityModel 6.0.0
  • Microsoft.AspNetCore.Authentication.JwtBearer

Add the connection to VGIdentityServer

Open the your startup class and go to the method ConfigureServices

public class Startup
{
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }


        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //services.Configure<VGConfiguration>(options => Configuration.GetSection("VGConfiguration").Bind(options));
            services.AddControllers();

 

            services.AddAuthentication("Bearer")
            .AddJwtBearer("Bearer", options =>
            {
                options.Authority = "<VGIdentityServerUrl>";
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false
                };
                options.Events = new JwtBearerEvents
                {
                    OnTokenValidated = ctx =>
                    {
                        var principal = ctx.Principal;
                        var authorization = ctx.HttpContext.Request.Headers[HeaderNames.Authorization];
                        if (AuthenticationHeaderValue.TryParse(authorization, out var headerValue))
                        {
                            // we have a valid AuthenticationHeaderValue that has the following details:

                            var scheme = headerValue.Scheme;//bearer
                            var token = headerValue.Parameter;//token

                            var client = new HttpClient();

                            UserInfoResponse userInfo = client.GetUserInfoAsync(new UserInfoRequest()
                            {
                                Address = "<VGIdentityServerUrl>/connect/userinfo",
                                Token = token
                            }).Result;

                            var claims = userInfo.Claims;
                            RequestPipe requestPipe = (RequestPipe)ctx.HttpContext.RequestServices.GetService(typeof(RequestPipe));

                            if (requestPipe != null && userInfo?.Claims != null)
                            {
                                requestPipe.Claims = new System.Collections.Generic.List<System.Security.Claims.Claim>(userInfo.Claims);
                                var permissions = claims.FirstOrDefault(x => x.Type == "vgPermissions").Value;
                                var roles = claims.FirstOrDefault(x => x.Type == "vgRoles").Value;

                                string[] lstPermissions = permissions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                string[] lstRoles = roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                                requestPipe.lstRoles = new List<string>(lstRoles);
                                requestPipe.lstPermission = new List<string>(lstPermissions);

                            }
                            //check if claims contains permissions And/or roles

                        }
                        return Task.CompletedTask;
                    },
                };
            });

            services.AddHttpContextAccessor();
            services.AddScoped<RequestPipe>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
}

How to get the claims ?

How to get the claims (roles, permissions) of the user in Web API to apply the security

var client = new HttpClient();

UserInfoResponse userInfo = client.GetUserInfoAsync(new UserInfoRequest()
{
    Address = "<VGIdentityServerUrl>/connect/userinfo",
    Token = token
}).Result;

var claims = userInfo.Claims;
RequestPipe requestPipe = (RequestPipe)ctx.HttpContext.RequestServices.GetService(typeof(RequestPipe));

if (requestPipe != null && userInfo?.Claims != null)
{
    requestPipe.Claims = new System.Collections.Generic.List<System.Security.Claims.Claim>(userInfo.Claims);
    var permissions = claims.FirstOrDefault(x => x.Type == "vgPermissions").Value;
    var roles = claims.FirstOrDefault(x => x.Type == "vgRoles").Value;

    string[] lstPermissions = permissions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    string[] lstRoles = roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

    requestPipe.lstRoles = new List<string>(lstRoles);
    requestPipe.lstPermission = new List<string>(lstPermissions);

}

How to secure your method ?

You need to add the meta attribut [Authorize]

[HttpGet("Add")]
[Authorize()]
public IActionResult Add(int a, int b)
{
      RequestPipe requestPipe = (RequestPipe)_httpContextAccessor.HttpContext.RequestServices.GetService(typeof(RequestPipe));
      if (requestPipe == null)
          return Unauthorized();

      if (!requestPipe.lstPermission.Contains("CanAdd"))
      {
           return Unauthorized();
      }
      return Ok(a + b);
}