asp.net-core.net-6.0claimsgenericprincipal

Adding claims to httpcontext in asp.net core (Controller test)


I am trying to make change to my controller test method by using a property from token which I am using to identify a property for my controller next steps

Old Situation:

Controller

var myPropertyName = HttpContext.User.Identity!.Name;
var myProperty = _myDataRepository.GetDetailsByName(myPropertyName);

Test method

MyProperty myProperty = new()
        {
            MyLim = 1,
            MyName = "Controller Test"
        };
        wasValidOnce = false;
        myDataRepository.Setup(_ => _.GetDetailsByName(It.IsAny<string>(), false)).Returns(myProperty);
        sut.ControllerContext.HttpContext = new DefaultHttpContext
        {
            User = new GenericPrincipal(new GenericIdentity("MyTestID"), new string[] { "myRole" })
        };

Post change my controller is below:

var id = HttpContext.User.Claims.FirstOrDefault(c => c.Type == "myid")?.Value;//myid is a property which is present in the claims
        var allItems = _myRepository.RetrieveAllItems();

        var myPropertyId = allItems.AsEnumerable().FirstOrDefault(a => a.myId.ToString().Equals(id)).foreignkeyIdColumn;

        var myProperty = _myDataRepository.GetDetailsById(myPropertyId);//GetDetailsByName and GetDetailsById give the entire table in response

Now I need to modify the test method so it works for the latest change in controller.

I did following changes

MyProperty myProperty = new()
        {
            MyLim = 1,
            MyName = "Controller Test"
        };
referenceDataRepository.Setup(_ => _.GetDetailsById(It.IsAny<int>())).Returns(myProperty);

 Guid id = Guid.NewGuid();

        sut.ControllerContext.HttpContext = new DefaultHttpContext
        {
            User = new GenericPrincipal(new GenericIdentity("MyTestID"), new string[] { "Role" }) { Claims = new List<Claim> { new Claim("myid", clientId.ToString()) } }            
        }; // but getting error in Claim: Property or indexer 'property' cannot be assigned to -- it is read only

How do I add myid as claims so it can be used in controller to resolve following line of code: var id = HttpContext.User.Claims.FirstOrDefault(c => c.Type == "myid")?.Value;


Solution

  • Here is my code sample:

    MyClaimsTransformation.cs

    using Microsoft.AspNetCore.Authentication;
    using System.Security.Claims;
    
    namespace WebApplication1
    {
        public class MyClaimsTransformation : IClaimsTransformation
        {
    
            public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
            {
                ClaimsIdentity claimsIdentity = new ClaimsIdentity();
                var claimType = "myNewClaim";
                claimsIdentity.AddClaim(new Claim(claimType, "myClaimValue"));
                principal.AddIdentity(claimsIdentity);
                return Task.FromResult(principal);
            }
        }
    
    }
    

    You need to add the service

    Program.cs

    builder.Services.AddSingleton<IClaimsTransformation, MyClaimsTransformation>();
    

    Then you can get the value from Users

    the value is passed

    For more details you can check this:https://learn.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0