Search code examples
asp.net-coreasp.net-identity

How to create an Asp.Net Identity Policy that represents a Logged In user?


I have a slightly unusual requirement: I need to create a policy in Asp.Net Identity that will represent a logged-in user. I want this in preference to actually checking if the user is logged in, so I want to be able to do:

<SomeContent>
   // This should be visible to anyone, whether logged in or not
</SomeContent

<AuthorizeView Policy="LoggedInUser">
   // This should be visible only to logged in users
   // unless the 'no policies' config option is enabled
</AuthorizeView>

<MoreContent>
   // This should be visible to anyone, whether logged in or not
</MoreContent

The reason I want to use a policy is that my app will have an option to disable policies and roles (for people who don't care about them). I can do this by checking the config at startup, and if the 'no roles/policies' config setting is enabled, I can do this:

if( opts.UseRolesAndPolicies() == true )
{
// Roles/policies are disabled, so return true whenever the policy is checked
config.AddPolicy("LoggedInUser, policy => 
            policy.RequireAssertion(context => true));
}
else
{
// Define a policy that only returns true if the user is logged in
config.AddPolicy("LoggedInUser, policy => 
            policy.RequireAssertion(context => 
                            /* WHAT GOES HERE?!? */ ));
}

which will allow access to the entitled content for everyone, regardless of whether they're logged in, a member or a role etc.

The question is, how do I define the policy to represent "allow if the user is logged in" when the 'no roles/policies' option is not set? What would I use in the AddPolicy check to see if a user is logged in? I guess I could use the RequireAssertion method, and in the function check the authenticationStateProvider for a user, but is there a better way? I'm doing this in a Blazor server app, if it makes a difference (probably not...).


Solution

  • Actually... i saw you did it right here config.AddPolicy("LoggedInUser, policy => policy.RequireAssertion(context => true));, that's the way you add the policy.

    And if you want to modify the policy based on some of your config on appSettings, this describe the idea

    // Define policies, you can have multiple policy, register as many as you want
    services.AddAuthorization(opts =>
                {
                    var section = configuration.GetSection("yourSection");
                    if (string.IsNullOrEmpty(section["haveConfigRole?"]))
                    {
                        opts.AddPolicy("DefaultPolicy", p =>
                        {
                            p.RequireAuthenticatedUser();
                            p.RequireRole(section["haveConfigRole?"]);
                            p.RequireRole(section["haveConfigRole?"]);
                            p.RequireRole(section["haveConfigRole?"]);
                        });
                    }
                    else
                    {
                        opts.AddPolicy("DefaultPolicy", p =>
                        {
                            p.RequireAuthenticatedUser();
                        });
                    }
                });
    
    // Using some specific policy:
    [Authorize(Policy = "DefaultPolicy")]