Role store via role manager throws when no claims (version 6.7.0)
See original GitHub issueHi, first of all thanks for this great library. Unfortunately, I’m experiencing an issue after upgrading it to the latest version, and I think I have tracked the error up to its origin: it should be line 102 in RoleStore.cs (https://github.com/matteofabbri/AspNetCore.Identity.Mongo/blob/master/AspNetCore.Identity.Mongo/Stores/RoleStore.cs). In my authentication code, claims are only optionally used in connection with roles; so the code collects them if they are present, otherwise it just returns the role name. This worked without issues before upgrading. Now instead it throws. My code is like this:
// collect claims from both user and its role(s)
IList<Claim> userClaims = await _userManager.GetClaimsAsync(user);
claims.AddRange(userClaims);
// claims from user roles
IList<string> userRoles = await _userManager.GetRolesAsync(user);
foreach (string userRole in userRoles)
{
claims.Add(new Claim(ClaimTypes.Role, userRole));
MongoRole role = await _roleManager.FindByNameAsync(userRole);
if (role != null && _roleManager.SupportsRoleClaims)
{
IList<Claim> roleClaims = await _roleManager.GetClaimsAsync(role);
foreach (Claim roleClaim in roleClaims)
{
claims.Add(roleClaim);
}
}
}
Now this throws a null exception at _roleManager.GetClaimsAsync, because effectively in the database the Claims property of the role is null. In your code, at the line quoted above, I find this:
return dbRole.Claims.Select(e => new Claim(e.ClaimType, e.ClaimValue)).ToList();
which of course throws when Claims is null. Could you please add some resiliency in this case, e.g.:
return dbRole.Claims != null? dbRole.Claims.Select(e => new Claim(e.ClaimType, e.ClaimValue)).ToList() : new List<Claim>();
or the like?
Here is the full exception stack for reference:
System.ArgumentNullException: Value cannot be null. (Parameter 'source')
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at AspNetCore.Identity.Mongo.Stores.RoleStore`1.GetClaimsAsync(TRole role, CancellationToken cancellationToken)
at CadmusApi.Controllers.AuthenticationController.GetUserClaims(ApplicationUser user) in C:\Projects\Core20\CadmusApi\CadmusApi\Controllers\AuthenticationController.cs:line 89
at CadmusApi.Controllers.AuthenticationController.Login(LoginBindingModel model) in C:\Projects\Core20\CadmusApi\CadmusApi\Controllers\AuthenticationController.cs:line 121
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Issue Analytics
- State:
- Created 3 years ago
- Comments:5

Top Related StackOverflow Question
Thanks, I derived my own
ApplicationRolefromMongoRoleand instantiated theClaimscollection its constructors. Once deleted and rebuilt, the database has now an empty array instead of null.MongoRolealready contains initializing of Claims property. When you inherit your own realization don’t forget to inherit constructors. Like: