<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carlos Jimenez</title>
    <description>The latest articles on DEV Community by Carlos Jimenez (@cmjimenez90).</description>
    <link>https://dev.to/cmjimenez90</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F100634%2F99d1334f-c99b-4aab-b338-e33048c8f286.jpg</url>
      <title>DEV Community: Carlos Jimenez</title>
      <link>https://dev.to/cmjimenez90</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cmjimenez90"/>
    <language>en</language>
    <item>
      <title>Resource Based Authorization using Razor Pages - PART 2</title>
      <dc:creator>Carlos Jimenez</dc:creator>
      <pubDate>Sun, 29 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/cmjimenez90/resource-based-authorization-using-razor-pages-part-2-4jbl</link>
      <guid>https://dev.to/cmjimenez90/resource-based-authorization-using-razor-pages-part-2-4jbl</guid>
      <description>&lt;p&gt;In part 1 of Requiring Authorization to Access your Web Application's Resources, we covered how to ensure your users were members of the administrator role to be able to complete specific actions. If you missed it or would like to refresh your memory please check it out &lt;a href="https://www.cmjimenez.com/blog/resource-based-authorization-using-razor-pages-part1"&gt;here&lt;/a&gt;. In part 2, we are going to look on how to expand this capability. Previously, we stated that we had two requirements regarding authorization.&lt;/p&gt;

&lt;p&gt;Those requirements were as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users can only create new debtors with an administrator role.&lt;/li&gt;
&lt;li&gt;Users can only make changes to an existing debtor if they are the creator of the debtor entity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using the same application from part 1, we are going to create a custom authorization requirement and authorization handler. This will allow us to complete our second requirement of making sure only the user who created a debtor is able to make modifications to it. The code of this application can be found on my &lt;a href="https://github.com/cmjimenez90/DebtorApplication"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Authorization Policies
&lt;/h2&gt;

&lt;p&gt;Before we can enforce this requirement, we will need to create the necessary authorization requirement and handler. The requirement in this case is used to map our application configuration and authorization handler. It is a basic class that just implements an interface, "IAuthorizationRequirement". We will call it the "SameDebtorOwnerRequirment" to help reflect its purpose.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class SameDebtorOwnerRequirment : IAuthorizationRequirement
 {
 }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The actual logic that will handle the authorization requirements will be defined in our handler. The handler extends the base class "AuthorizationHandler". Here we will map our requirement, the "SameDebtorOwnerRequirement" to the resource we are going to protect, the Debtor. We will implement most of our logic in the HandleRequirmentAsync method that we will need to override.&lt;/p&gt;

&lt;p&gt;Our logic will consist of getting the user id of the signed-in user and making sure that it matches the id of the owner stored on the debtor resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class DebtorAuthorizationHandler : AuthorizationHandler&amp;lt;SameDebtorOwnerRequirment, Debtor&amp;gt;
{
        private readonly UserManager&amp;lt;IdentityUser&amp;gt; _userManager;

        public DebtorAuthorizationHandler(UserManager&amp;lt;IdentityUser&amp;gt; userManager) =&amp;gt; _userManager = userManager;

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, SameDebtorOwnerRequirment requirement, Debtor resource)
        {
            string userID = _userManager.GetUserId(context.User);
            if (userID != null &amp;amp;&amp;amp; resource != null)
            {
                if ((userID == resource.OwnerID) &amp;amp;&amp;amp; context.User.IsInRole(ApplicationRoles.Administrator.ToString()))
                {
                    context.Succeed(requirement);
                }
            }
            return Task.CompletedTask;
        }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If the authorization check passes, then a success is recorded in the web application context and returned. If not, then the task is returned as complete, but the context is not modified. This is because you may have multiple requirements defined in your application, and they will not run if you sent a failure in the context instead. This allows you to create multiple requirements to account for multiple scenarios. If you would like to see an example of why you would want to do this, please check out Microsoft's example using &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/security/authorization/policies?view=aspnetcore-3.1"&gt;.Net Core&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storing the resource creator in the Debtor model
&lt;/h2&gt;

&lt;p&gt;Our next step in the process is to make sure that we store the id of the current user in our Debtor model, as this is necessary for our authorization requirement. We will add a "String" property to our Debtor model to store the User's id as "OwnerID". We will then make sure to store this information whenever a new Debtor is created.&lt;/p&gt;

&lt;p&gt;Debtor class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  public class Debtor
  {
        public int DebtorID { get; set; }
        [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$")]
        [Required]
        public string FirstName { get; set; }
        [RegularExpression(@"^[A-Z]+[a-zA-Z""'\s-]*$")]
        [Required]
        public string LastName { get; set; }
        [DataType(DataType.EmailAddress)]
        [Required]
        public string Email { get; set; }
        [Iban]
        public string IBAN { get; set; }
        public string OwnerID { get; set; }
        public virtual ICollection&amp;lt;Invoice&amp;gt; Invoices { get; set; }
  }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To add the user id to the Debtor, we just need to use the UserManager service to get the id of the current user and store this before saving the Debtor entity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; [Authorize(Roles = "Administrator")]
    public class NewDebtorModel : BasePageModel
    {   
        ....CODE REMOVED FOR SIMPLICITY

        public async Task&amp;lt;IActionResult&amp;gt; OnPostAsync([Bind("FirstName,LastName,Email,IBAN")]Debtor debtor)
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            debtor.OwnerID = UserManager.GetUserId(User);
            Context.Add(debtor);
            await Context.SaveChangesAsync();

            return RedirectToPage("./ViewDebtor", new { id = debtor.DebtorID });
        }
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Before we can use our newly defined handler and requirement, we will need to add them to our startup.cs. In our ConfigureServices method, we will add our requirement and map it to a name. In our case, "DebtorEditPolicy".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
{
....
services.AddAuthorization(options =&amp;gt;
            {
                options.AddPolicy("DebtorEditPolicy", policy =&amp;gt; policy.Requirements.Add(new SameDebtorOwnerRequirment()));
            });

            services.AddScoped&amp;lt;IAuthorizationHandler, DebtorAuthorizationHandler&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally, we are now ready to add support to our pages to utilize our defined requirements and handler. To support this, we will need to make sure that our razor page has access to the web application's authorization service. This can be accomplished by passing in the authorization service to the page's constructor via dependency injection. Afterwards, we can then utilize the authorization service in our page's methods to enforce our requirements.&lt;/p&gt;

&lt;p&gt;One of our main requirements is that our created Debtors can only be modified by their owner. In our update metho,d we will add the following to account for this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;ActionResult&amp;gt; OnPostAsync(int? id)
{
            ....

            Debtor debtorToEdit = await Context.Debtors.FirstOrDefaultAsync(item =&amp;gt; item.DebtorID == id);

            AuthorizationResult result = await AuthorizationService.AuthorizeAsync(User, debtorToEdit, "DebtorEditPolicy");
            if(!result.Succeeded)
            {
               return new ForbidResult();
            }

            ....
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If the current user is not signed in or not the creator of the resource, they will then receive an access denied message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--46jJUMOE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buttercms.com/gwcPuqRaQIOqc85TF7mM" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--46jJUMOE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buttercms.com/gwcPuqRaQIOqc85TF7mM" alt="debtor_access_denied_create.png"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>razorpages</category>
      <category>authorization</category>
    </item>
    <item>
      <title>Resource Based Authorization using Razor Pages - PART 1</title>
      <dc:creator>Carlos Jimenez</dc:creator>
      <pubDate>Thu, 07 Nov 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/cmjimenez90/requiring-authorization-to-access-your-web-application-s-resources-part-1-12ld</link>
      <guid>https://dev.to/cmjimenez90/requiring-authorization-to-access-your-web-application-s-resources-part-1-12ld</guid>
      <description>&lt;p&gt;User's of your web application will access a variety of different resources over time. Often, access to these resources will need to be limited according to some predefined criteria. You can accomplish this in a .Net Core Razor Pages application by adding authorization to the web app. We will cover how to add authorization to your razor page's application using a demo application. This demo application provides a web-based interface to manage debtors and any associated invoices they may have. This post will be split into two separate posts. This first one will cover adding the roles to your application and requiring the administrator role to create a new debtor. The second post will include restricting the ability to modify an existing debtor to only the debtor's creator.&lt;/p&gt;

&lt;p&gt;Before adding authorization to your application, your .Net Core app needs to have an identity, and an authentication system implemented. This article will not cover how to add authentication to your application. The demo application in this example uses .Net Core's native authentication, along with Google authentication as a secondary identity provider. The Github for this project can be found &lt;a href="https://github.com/cmjimenez90/DebtorApplication"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the Authorization Requirements
&lt;/h2&gt;

&lt;p&gt;To add authorization to your application, you will first need to understand what you are trying to accomplish. In other words, what are your goals?&lt;/p&gt;

&lt;p&gt;In this case, our demo debtor application has the following requirements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users can only create new debtors with an administrator role.&lt;/li&gt;
&lt;li&gt;Users can only make changes to an existing debtor if they are the creator of the debtor entity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Requirement 1: Creating a New Debtor Requires the Administrator Role
&lt;/h3&gt;

&lt;p&gt;Adding role-based authorization to your application is pretty straight-forward. .Net authorization can be enabled in your web application's configuration on start-up using some default settings. The debtor application uses the default identity set-up for local authentication by calling the IServiceCollection's AddDefaultIdentity&amp;lt;&amp;gt; method chain using .Net's standard configuration. We will add the role support to the method chain in our Startup.cs's ConfigureServices method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDefaultIdentity&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IdentityUser&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDefaultUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UIFramework&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Bootstrap4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRoles&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IdentityRole&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddEntityFrameworkStores&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After enabling roles in the default identity configuration, we will need to seed the database with whatever roles your application will utilize. This will be a multiple-step process as we will be separating some of the configurations between two different classes. We will first create a new class where we can define our application roles. In this case, the debtor application will use the following two roles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Administrator&lt;/li&gt;
&lt;li&gt;User&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I chose to implement a new enum class called ApplicationRoles.&lt;/p&gt;

&lt;p&gt;Here is what the class files look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;ApplicationRoles&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Administrator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We will use this class to seed our database with these predefined roles.&lt;/p&gt;

&lt;p&gt;Next, to manage our seeding, we will create a new class called DefaultAdminConfiguration. This class will seed the database with these two roles and also create a default admin account. The credentials for the default admin account will be loaded from our configuration file under the section of "AdminUserSettings." We will call the Initialize function of our DefaultAdminConfiguration in our startup.cs's Configure method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DefaultAdminConfiguration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="n"&gt;IConfiguration&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;roleManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;RoleManager&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IdentityRole&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;serviceProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetRequiredService&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserManager&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IdentityUser&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;IdentityResult&lt;/span&gt; &lt;span class="n"&gt;identityResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApplicationRoles&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(!(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;roleManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RoleExistsAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;identityResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;roleManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IdentityRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="n"&gt;IdentityUser&lt;/span&gt; &lt;span class="n"&gt;adminUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;IdentityUser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="n"&gt;UserName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AdminUserSettings"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
      &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AdminUserSettings"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"AdminUserSettings"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;IdentityUser&lt;/span&gt; &lt;span class="n"&gt;foundUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;userManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindByEmailAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adminUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;foundUser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="n"&gt;IdentityResult&lt;/span&gt; &lt;span class="n"&gt;createdUser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;userManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adminUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;createdUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Succeeded&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;userManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddToRoleAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adminUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApplicationRoles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Administrator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());}}}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we add DefaultAdminConfiguration to our applications Startup.cs and call its initialize method in the Configure method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IHostingEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IServiceProvider&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt; 
  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseHttpsRedirection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseStaticFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseCookiePolicy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="n"&gt;DefaultAdminConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Wait&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMvc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To require that users of our application be a part of the administrator role to create a new debtor, we will need to add it to the designated pages. Open up the code behind of the CreateDebtor Razor Page located in our application's Pages/Debtors directory. We are going to add the Authorize attribute to our class with the role of "Administrator."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Roles&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Administrator"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewDebtorModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BasePageModel&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, if we run the application and try to create a new Debtor without having the administrator role, you will receive an access denied.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--46jJUMOE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buttercms.com/gwcPuqRaQIOqc85TF7mM" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--46jJUMOE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.buttercms.com/gwcPuqRaQIOqc85TF7mM" alt="debtor_access_denied_create.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding role-based authorization is pretty straight forward. In part 2, we will see how we can use .Net's IAuthorizationRequirement and AuthorizationHandler to restrict a user's ability to modify debtors in the application.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>razorpages</category>
      <category>authorization</category>
    </item>
    <item>
      <title>Fighting Anxiety and Impostor Syndrome by Blogging</title>
      <dc:creator>Carlos Jimenez</dc:creator>
      <pubDate>Tue, 27 Aug 2019 23:14:31 +0000</pubDate>
      <link>https://dev.to/cmjimenez90/fighting-anxiety-and-impostor-syndrome-by-blogging-516k</link>
      <guid>https://dev.to/cmjimenez90/fighting-anxiety-and-impostor-syndrome-by-blogging-516k</guid>
      <description>&lt;p&gt;It was around February of 2018 when I decided to purchase my domains. I was a little excited, so I purchased three of them: cmjimenez.com, cmjimenez.net, cmjimenez.me. You know, just in case someone else might be looking to purchase them as well -_-. So, now I had three domains and no idea what I was going to do with any of them. &lt;/p&gt;

&lt;p&gt;I spend a lot of my free time reading. Between &lt;a href="https://dev.to"&gt;Dev.To&lt;/a&gt;, &lt;a href="https://reddit.com"&gt;Reddit&lt;/a&gt;, or &lt;a href="https://hackernoon.com"&gt;Hackernoon&lt;/a&gt;, I can always manage to find something that would peak my interest. One topic that I always found interesting was on "why you should create your own blog". There were a number of reasons on why it was beneficial. Some post elaborated on how maintaining a blog would provide a way for you to document your work. Others highlighted the importance of being able to share their views and their unique approaches to solving certain problems. However, one of the most interesting things that I read about was about how creating a blog could also help boost my confidence. I never thought about it from that perspective before and I was willing to give it a try.&lt;/p&gt;

&lt;h3&gt;
  
  
  So, how would creating a blog help boost my confidence?
&lt;/h3&gt;

&lt;p&gt;I often get anxiety when communicating with others - especially in a professional setting. I am pretty sure this anxiety stems from the slight insecurity that I have of not wanting to be wrong. I guess it is what is referred to as &lt;a href="https://en.wikipedia.org/wiki/Impostor_syndrome"&gt;impostor syndrome&lt;/a&gt;. I am also not the only one who suffers from this detrimental mind state. I have read quite a few post that were written by individuals who also suffer from this way of thinking. &lt;/p&gt;

&lt;p&gt;I think a lot of us are scared of being judged. My mind tends to think the worst in these situations, even if it is unwarranted. My drive to be a perfectionist tends to amplify these thoughts as well. By putting my self out there and writing a blog, I am making my self vulnerable. I will be sharing my views with others and in doing so, I hope to become more comfortable in these sort of situations. Now, I know there is nothing wrong with putting our selves out there. Hell, there is nothing wrong about being wrong either! When we are wrong, it provides an opportunity to learn something new. &lt;/p&gt;

&lt;p&gt;So if your on the fence on creating a blog, just do it. If not for sharing with others, at least do it for your self. You have nothing to loose! &lt;/p&gt;

&lt;h3&gt;
  
  
  So here we are...
&lt;/h3&gt;

&lt;p&gt;I started working on my website finally around December of 2018 and by February I released the first iteration of my website. It is now August of 2019 and I am finally releasing my blog. It probably should not have taken that long but that is a subject for another post in the future. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cross post from my blog: &lt;a href="https://www.cmjimenez.com/blog/why-i-created-a-blog"&gt;https://www.cmjimenez.com/blog/why-i-created-a-blog&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>impostorsyndrome</category>
      <category>blog</category>
      <category>anxiety</category>
    </item>
  </channel>
</rss>
