0

I'm trying to transform.NetCore 3.1 Code from Bearer Token implementation to Cookie-based implementation Also trying to make Role-based authorization work with existing code. Can you please help me to change this code? The below code shows currently how Bearer Token is retrieved and the next part shows how role-based authorization is implemented in code.

Here is the current Bearer Token implementation.

var key = Encoding.ASCII.GetBytes(Configuration["AppSettings:Secret"]);

            var signingKey = new SymmetricSecurityKey(key);

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    IssuerSigningKey = signingKey,
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

Following annotation currently used for Role-based Authorization -

[Authorize(Roles = "1")]
[Route("api/[controller]")]
[ApiController]

public class JobLogsController : ControllerBase
{
    private readonly EtpRepoContext _context;
    private IJobLogsRepository _jobLogsRepository;
    private IConfiguration _configuration;

    public JobLogsController(EtpRepoContext context, IJobLogsRepository jobLogsRepository, IConfiguration configuration)
    {
        _context = context;
        _jobLogsRepository = jobLogsRepository;
        _configuration = configuration;
    }

    // GET: api/JobLogs
    [HttpGet]
    public async Task<ActionResult<IEnumerable<JobLog>>> GetJobLog()
    {
        return await _context.JobLog.ToListAsync();
    }

    // GET: api/JobLogs/5
    [HttpGet("{id}")]
    [ProducesResponseType(typeof(JobDetail), 200)]
    [ProducesResponseType(typeof(string), 400)]
    public IActionResult FindById([FromRoute] String id)
    {
        string contentStr = "";
        try
        {
            if(id.Length >= 10)
            {
                contentStr = _jobLogsRepository.GetLogById(id);
            }
            else
            {
                contentStr = _jobLogsRepository.GetFileById(id);
            }
            
            var content = Newtonsoft.Json.JsonConvert.SerializeObject(new { content = contentStr });
            return Ok(content);
        }
        catch (Exception ex)
        {
            return StatusCode(500, "Internal server error");
        }
    }

This is how the Microsoft identity model is used to claim the token.

public class ClaimsTransformer : IClaimsTransformation
    {
        public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            ClaimsIdentity claimsIdentity = (ClaimsIdentity)principal.Identity;

            // flatten realm_access because Microsoft identity model doesn't support nested claims
            // by map it to Microsoft identity model, because automatic JWT bearer token mapping already processed here
            if (claimsIdentity.IsAuthenticated && claimsIdentity.HasClaim((claim) => claim.Type == "identity"))
            {
                var realmAccessClaim = claimsIdentity.FindFirst((claim) => claim.Type == "identity");
                dynamic realmAccessAsDict = JsonConvert.DeserializeObject<Object>(realmAccessClaim.Value);
                string role = realmAccessAsDict.role.ToString();
                claimsIdentity.AddClaim(new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", role));

                //var role = realmAccessClaim.
                //var realmAccessAsDict = JsonConvert.DeserializeObject<Object>(realmAccessClaim.Value);
                /*if (realmAccessAsDict["role"] != null)
                {
                    foreach (var role in realmAccessAsDict["role"])
                    {
                        claimsIdentity.AddClaim(new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", role));
                    }
                }*/
            }

            return Task.FromResult(principal);
        }
    }
}
Partha
  • 413
  • 2
  • 5
  • 16
  • Do you want to save token in cookie, or use cookie authentication directly? – Karney. Dec 04 '20 at 03:33
  • Thank for looking into it. We are saving the token in the cookie which is done in UI layer and in Service Layer (build in .net Core 3.1) planning to get the same cookie and use it for Role based authorization. I'm trying to find a solution for Service layer. Given code is for Service layer which was implemented Bearer Token but now we need to move to Cookie based implementation. – Partha Dec 04 '20 at 16:23
  • Hi Guys! Checking if anyone got a chance to look into this? Appreciate your help. – Partha Dec 07 '20 at 14:58
  • Where do you want to configure role-base authorization, in startup? – Karney. Dec 08 '20 at 06:28

0 Answers0