locked
Where can I find up to date information on adding Identity services? RRS feed

  • Question

  • User1457412228 posted

    Specifically I have the code that is added automatically when you select individual security configuration in a new project, and I am trying to add the IdentityRole to that.   

    I followed the documentation on Pluralsite in the security course for dot net core, but it is almost two years old.

    Following that, I would want to add 

    services.AddIdentity<IdentityUser, IdentityRole>();

    However, I see that someone has now changed that to be services.AddDefaultIdentity<IdentityUser>() and it has no place to add an IdentityRole. 

    If I remove the services..DefaultIdentity and add in the services.AddIdentity it blows up.  And I am sure you can't use both.  

    My goal is to inject into one of my models.

    Please type fast, or the answer will be obsolete again(smile)

    Thursday, June 13, 2019 5:22 AM

Answers

  • User475983607 posted

    Modify the IdentityHostingStartup to include the RoleManager.

    services.AddDefaultIdentity<ApplicationUser>()
        .AddRoles<IdentityRole>()
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    Inject the Role Manager.

        public class IndexModel : PageModel
        {
            private readonly RoleManager<IdentityRole> _roleManager; 
            public IndexModel(RoleManager<IdentityRole> roleManager)
            {
                _roleManager = roleManager;
            }
            public void OnGet()
            {
                Roles = _roleManager.Roles.ToList();
            }
    
            [BindProperty]
            public List<IdentityRole> Roles { get; set; }
        }   
    @foreach(var r in Model.Roles)
    {
        <div>@r.Name</div>
    }

     Results

    Admin
    Member

    My DB

    SELECT [Id]
          ,[Name]
          ,[NormalizedName]
          ,[ConcurrencyStamp]
      FROM [dbo].[AspNetRoles]
    GO
    
    C74AE8AC-F35E-4C24-B94A-22F8A451E1A6	Admin	ADMIN	E1C7E288-DC39-4909-A876-AA35A657B3CE
    DCFF0FBA-CC3A-4A60-8611-228EC3BC5A44	Member	MEMBER	5F709126-5655-4B3E-9567-7313CE59BEFF

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, June 13, 2019 2:16 PM

All replies

  • User-1038772411 posted

    Hello talldaniel,

    Kindly refer this below link where i think you can get latest , I hope this will help you. 

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/customize-identity-model?view=aspnetcore-2.2

    Thank you.

    Thursday, June 13, 2019 6:28 AM
  • User-1764593085 posted

    Hi talldaniel,

    talldaniel

    I see that someone has now changed that to be services.AddDefaultIdentity<IdentityUser>() and it has no place to add an IdentityRole. 

    if you use asp.net core 2.2,you could use below code to register identityRole:

    services.AddDefaultIdentity<IdentityUser>()
                    .AddRoles<IdentityRole>()
                    .AddDefaultUI(UIFramework.Bootstrap4)
                    .AddEntityFrameworkStores<ApplicationDbContext>();

    Refer to https://github.com/aspnet/Identity/issues/1813

    Best Regards,

    Xing

    Thursday, June 13, 2019 6:35 AM
  • User1457412228 posted

    Thanks,

    (as a side note, I accidentally posted my password, so I changed it.  When I tried using the app, it continued to work until I logged out and then back in.  I am surprised that the db connection string is apparently not used once the connection is established.)

    I get this error when I try that, with this startup.

    If I move the "add role" code for admin to the constructor it appears to execute without complaint, but no role is actually added to any database table that I can find in the dbo.aspnet... tables.

    System.ObjectDisposedException
    HResult=0x80131622
    Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
    Object name: 'AsyncDisposer'.
    Source=Microsoft.EntityFrameworkCore
    StackTrace:
    at Microsoft.EntityFrameworkCore.Internal.ConcurrencyDetector.AsyncDisposer.Dispose()
    at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext()
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<ExecuteSingletonAsyncQuery>d__21`1.MoveNext()
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at Microsoft.AspNetCore.Identity.RoleManager`1.<RoleExistsAsync>d__33.MoveNext()
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
    at antiatsSecure.Pages.TestPageForAddingRolesModel.<MakeMeAnAdmin>d__6.MoveNext() in C:\Users\Daniel\Source\Repos\antiatsrazor\antiatsSecure\Pages\TestPageForAddingRoles.cshtml.cs:line 45

    public class TestPageForAddingRolesModel : PageModel
    {
    
    private readonly SignInManager<IdentityUser> _signInManager;
    private readonly UserManager<IdentityUser> _userManager;
    private readonly ILogger<RegisterModel> _logger;
    private RoleManager<IdentityRole> _roleManager;
    
    public TestPageForAddingRolesModel(
    UserManager<IdentityUser> userManager,
    SignInManager<IdentityUser> signInManager,
    ILogger<RegisterModel> logger,
    RoleManager<IdentityRole> roleManager)
    {
    _userManager = userManager;
    _signInManager = signInManager;
    _logger = logger;
    _roleManager = roleManager;
    
    
    }
    public void OnGet()
    {
    
    MakeMeAnAdmin();
    }
    
    private async void MakeMeAnAdmin()
    {
    var userName = User.Identities.First<ClaimsIdentity>().Name;
    
    if(! await _roleManager.RoleExistsAsync("Admin"))
     public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<CookiePolicyOptions>(options =>
                {
                    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                    options.CheckConsentNeeded = context => true;
                    options.MinimumSameSitePolicy = SameSiteMode.None;
                });
                services.AddTransient<IEmailSender, EmailSender>();
                services.AddDbContext<ApplicationDbContext>(options =>
                 
                options.UseSqlServer(
                       @"Server=antiats.database.windows.net ---deleted
               
                services.AddDefaultIdentity<IdentityUser>()
                    .AddDefaultUI(UIFramework.Bootstrap4)
                    .AddRoles<IdentityRole>()
                    .AddEntityFrameworkStores<ApplicationDbContext>();
              
                services.AddMvc()
                    .AddRazorPagesOptions(options =>
                    {
                        
                        
                        //for production deployments
                        options.Conventions.AuthorizePage("/Index");
                        options.Conventions.AuthorizePage("/Open");
                        options.Conventions.AuthorizePage("/Pricing");
    
                        options.Conventions.AuthorizeFolder("/Pages/Shared");                   
                        options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
                        options.Conventions.AllowAnonymousToFolder("/Identity/Account");
                    })
                    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
                IFileProvider physicalProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory());
    
                services.AddSingleton<IFileProvider>(physicalProvider);
                services.Configure<IdentityOptions>(options =>
                {
                    // Password settings.
                    options.Password.RequireDigit = true;
                    options.Password.RequireLowercase = true;
                    options.Password.RequireNonAlphanumeric = true;
                    options.Password.RequireUppercase = true;
                    options.Password.RequiredLength = 6;
                    options.Password.RequiredUniqueChars = 1;
    
                    // Lockout settings.
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                    options.Lockout.MaxFailedAccessAttempts = 5;
                    options.Lockout.AllowedForNewUsers = true;
    
                    // User settings.
                    options.User.AllowedUserNameCharacters =
                    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                    options.User.RequireUniqueEmail = false;
                });
               
                services.ConfigureApplicationCookie(options =>
                {
                    // Cookie settings
                    //todo Determine if I want to increase the ExpireTimespan
                    options.Cookie.HttpOnly = true;
                    options.ExpireTimeSpan = TimeSpan.FromDays(100);
    
                    options.LoginPath = "/Identity/Account/Login";
                    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
                    options.SlidingExpiration = true;
                });
                
                
            }

    Thursday, June 13, 2019 1:01 PM
  • User475983607 posted

    I'm guessing that you created a new Razor pages project and selected "Individual Account".  This creates a Razor Page Class library (RPC) which is a DLL that contain Identity and the Identity UI.

    You must scaffold Identity to make changes to the code.

    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-2.2&tabs=visual-studio

    Thursday, June 13, 2019 1:11 PM
  • User1457412228 posted

    Thank you.  Yes, I have scaffolded the login.  However, the auto-generated boiler plate code for the startup does not appear to include anything for roles, nor do I see anything in the 30 possible scaffolded pages.

    To solve this I watched a pluralsite video and did as they suggested.  However, that code is obsolete, as it is almost 2 years old, so it doesn't work with how things are today and just blows up.

    I don't want to login someone, I want a roleManager injected into a page.   

    Thanks

    Thursday, June 13, 2019 1:20 PM
  • User475983607 posted

    Modify the IdentityHostingStartup to include the RoleManager.

    services.AddDefaultIdentity<ApplicationUser>()
        .AddRoles<IdentityRole>()
        .AddRoleManager<RoleManager<IdentityRole>>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    Inject the Role Manager.

        public class IndexModel : PageModel
        {
            private readonly RoleManager<IdentityRole> _roleManager; 
            public IndexModel(RoleManager<IdentityRole> roleManager)
            {
                _roleManager = roleManager;
            }
            public void OnGet()
            {
                Roles = _roleManager.Roles.ToList();
            }
    
            [BindProperty]
            public List<IdentityRole> Roles { get; set; }
        }   
    @foreach(var r in Model.Roles)
    {
        <div>@r.Name</div>
    }

     Results

    Admin
    Member

    My DB

    SELECT [Id]
          ,[Name]
          ,[NormalizedName]
          ,[ConcurrencyStamp]
      FROM [dbo].[AspNetRoles]
    GO
    
    C74AE8AC-F35E-4C24-B94A-22F8A451E1A6	Admin	ADMIN	E1C7E288-DC39-4909-A876-AA35A657B3CE
    DCFF0FBA-CC3A-4A60-8611-228EC3BC5A44	Member	MEMBER	5F709126-5655-4B3E-9567-7313CE59BEFF

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, June 13, 2019 2:16 PM
  • User1457412228 posted

    Thank you that works.

    For anyone reading this for the same problem, the trick is that you have to now add roles twice in startup.  Once for rolemanager, and once for roles.  

    MUCH appreciated mgebhard

    Thursday, June 13, 2019 2:45 PM