Search code examples
asp.net-coreidentityserver4

IdentityServer4 Reject Token Request If Custom Parameter Not Valid


I have this test client sending RequestToken:

var tokenResponse = await client.RequestTokenAsync(new TokenRequest
            {
                Address = disco.TokenEndpoint,
                GrantType = "password",
                ClientId = "My_Client",
                ClientSecret = "mysecret",
                Parameters =
                {
                    { "username", "[email protected]" },
                    { "password", "userpassword" },
                    { "logged_entity_id", "143" },
                    { "scope", "MyAPI" }
                }
            });

Now each user has a list of entity and I want to reject the token request if the value in the parameter "logged_entity_id" does not exist in the user's list of entity.

I was initially planning on checking it via IsActiveSync in my CustomProfileService but I can't seem to access the raw parameters in IsActiveSync method.

    public class CustomProfileService : IProfileService
    {
        protected UserManager<User> _userManager;

        public CustomProfileService(UserManager<User> userManager)
        {
            _userManager = userManager;
        }

        public Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var claims = new List<Claim>
            {
                new Claim("LoggedEntityId", context.ValidatedRequest.Raw["logged_entity_id"])
            };

            context.IssuedClaims.AddRange(claims);

            return Task.FromResult(0);
        }

        public Task IsActiveAsync(IsActiveContext context)
        {
            var user = _userManager.GetUserAsync(context.Subject).Result;
            // var entityId = Can't access logged_entity_id parameter here

            context.IsActive = user != null && user.DeletingDate == null && user.entities.Contains(entityId);
            return Task.FromResult(0);
        }
    }

I'm not really sure if this is where I should check and reject it.


Solution

  • In asp.net core you can register a dependency using the built-in dependency injection container. The dependency injection container supplies the IHttpContextAccessor to any classes that declare it as a dependency in their constructors:

    public void ConfigureServices(IServiceCollection services)
    {
         ...
         services.AddHttpContextAccessor();
         ...
    }
    

    Then in your class ,for example , in the implement of IProfileService :

    private readonly IHttpContextAccessor _httpContextAccessor;
    
    public CustomProfileService(IHttpContextAccessor httpContextAccessor)
    { 
         _httpContextAccessor = httpContextAccessor;
    }
    

    Then in IsActiveAsync method get the value by :

    var  id = _httpContextAccessor.HttpContext.Request.Form["logged_entity_id"].ToString();