<?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: Artem Medvedev</title>
    <description>The latest articles on DEV Community by Artem Medvedev (@ddtkey).</description>
    <link>https://dev.to/ddtkey</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%2F615286%2F81c431af-5db5-4697-bffe-fd0c7eecd729.jpeg</url>
      <title>DEV Community: Artem Medvedev</title>
      <link>https://dev.to/ddtkey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ddtkey"/>
    <language>en</language>
    <item>
      <title>Authorization mechanisms in Rust web applications</title>
      <dc:creator>Artem Medvedev</dc:creator>
      <pubDate>Fri, 14 May 2021 18:03:49 +0000</pubDate>
      <link>https://dev.to/ddtkey/authorization-mechanisms-in-rust-web-applications-27ag</link>
      <guid>https://dev.to/ddtkey/authorization-mechanisms-in-rust-web-applications-27ag</guid>
      <description>&lt;p&gt;To ensure application security, we use mechanisms such as authentication and authorization. I think many of you are familiar with these concepts and in this article we will focus on the concept of authorization and related access control models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzq2a9mm3e4gfh3guv73a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzq2a9mm3e4gfh3guv73a.png" alt="security"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
  &lt;em&gt;&lt;strong&gt;Definitions of terms used in the article&lt;/strong&gt;&lt;/em&gt;
  &lt;p&gt;It's important to understand the difference between authorization and authentication:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Authentication&lt;/em&gt;&lt;/strong&gt; – a process of verifying your identity and proving that you are a user of the system (by means of a password, token or any other form of credentials).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Authorization&lt;/em&gt;&lt;/strong&gt; - a mechanism whose task is to allow or deny a request for a specific system resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Access subject&lt;/em&gt;&lt;/strong&gt; – a user or process that is requesting access to the resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Access object&lt;/em&gt;&lt;/strong&gt; – on the contrary, it's a resource to which access is requested by the subject.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Crate&lt;/em&gt;&lt;/strong&gt; – a library or executable (binary) program in Rust.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;The authorization process includes the concept of &lt;strong&gt;&lt;em&gt;access control policy&lt;/em&gt;&lt;/strong&gt;, in accordance with which the set of permissible actions of a particular user (access subject) over the system resources (access objects) is determined.&lt;/p&gt;

&lt;p&gt;And also the &lt;strong&gt;&lt;em&gt;access control model&lt;/em&gt;&lt;/strong&gt; is a general scheme for delimiting access through a user policy, which we choose depending on various factors and system requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's take a look at the basic access control models:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;DAC&lt;/strong&gt; - &lt;em&gt;Discretionary access-control&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rx2bzzegyfnq8o3uwjo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rx2bzzegyfnq8o3uwjo.png" alt="Discretionary access-control"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This paradigm allows users to independently grant the right to any action on their data to other system participants, for which &lt;em&gt;access control lists&lt;/em&gt; (&lt;strong&gt;ACL&lt;/strong&gt;) are used.&lt;/p&gt;

&lt;p&gt;Most often used in cases where users directly own certain resources and can independently decide who to allow interaction with them.&lt;/p&gt;

&lt;p&gt;An example would be operating systems or social networks, where people independently change the visibility of their content.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;MAC&lt;/strong&gt; - &lt;em&gt;Mandatory access-control&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatq5t9tpuy5z116vrp1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatq5t9tpuy5z116vrp1u.png" alt="Mandatory access-control"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was developed for government purposes with a focus on application in extremely secure systems (for example, military), where it was most widespread.&lt;/p&gt;

&lt;p&gt;Data protection is based on confidentiality labels (level of secrecy or importance), through which the level of access of subjects is checked. As a rule, the rights are issued centrally by the management body.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;MAC&lt;/em&gt; is perhaps one of the most rigorous and secure models, but it comes with the complexity and high cost of implementing and maintaining the infrastructure around it (there are many ways that require careful planning).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;RBAC&lt;/strong&gt; - &lt;em&gt;Role-Based access-control&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most common and well-known model that fits well with business domains and correlates with job functions. It is a kind of development of &lt;em&gt;DAC&lt;/em&gt;, where privileges are grouped into their respective roles.&lt;/p&gt;

&lt;p&gt;Each subject can have a list of roles, where the role, in turn, can provide access to a certain list of objects.&lt;/p&gt;

&lt;p&gt;It should be noted that in RBAC the &lt;strong&gt;PBAC&lt;/strong&gt; (&lt;em&gt;Permission-Based access-control&lt;/em&gt;) model is sometimes allocated when a set of actions is allocated for each resource in the system (for example: &lt;code&gt;READ_DOCUMENT&lt;/code&gt;,&lt;code&gt;WRITE_DOCUMENT&lt;/code&gt;,&lt;code&gt;DELETE_DOCUMENT&lt;/code&gt;) and bind it with the subject through the relationship with roles, directly with the user, or a hybrid approach, when the subject can have a role and separate privileges.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;ABAC&lt;/strong&gt; - &lt;em&gt;Attribute-Based access-control&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jr9g106oo7t46476hdx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1jr9g106oo7t46476hdx.png" alt="Attribute-Based access-control"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this approach, it's necessary to maintain special policies that combine the attributes of subjects and objects, and the access decision is provided based on the analysis and comparison of these attributes.&lt;/p&gt;

&lt;p&gt;This is the most flexible of the described models with a huge number of possible combinations, which allows making decisions based on such parameters as request time, location, employee position, etc., but requires more detailed planning of policies to prevent unauthorized access.&lt;/p&gt;

&lt;p&gt;ABAC requires some mechanism for interpreting policies and some syntactic subset, which can entail execution time (in the case of a dynamic implementation) or compilation (in the case of code generation).&lt;/p&gt;

&lt;p&gt;You can read more about some of the models in &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html#permission-based-access-control" rel="noopener noreferrer"&gt;OWASP materials&lt;/a&gt; (Open Web Application Security Project) and in &lt;a href="https://www.ibm.com/docs/en/sig-and-i/10.0.0?topic=planning-access-control-models" rel="noopener noreferrer"&gt;IBM documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Access control is a very important part of web applications, since it is necessary to strictly observe the delimitation of access to resources and data (especially personal ones - the protection of which is provided for by legislative aspects), depending on the privileges of users.&lt;/p&gt;


&lt;h2&gt;
  
  
  What do we have in Rust web frameworks?
&lt;/h2&gt;

&lt;p&gt;Typically, to implement anti-tampering mechanisms in popular web frameworks (such as actix-web, Rocket, or tide), &lt;code&gt;Middleware&lt;/code&gt;, &lt;code&gt;FromRequest&lt;/code&gt;, or &lt;code&gt;Guard&lt;/code&gt; (&lt;code&gt;Filter&lt;/code&gt; in the case of warp) implementations are used.&lt;/p&gt;

&lt;p&gt;That is, in some kind of middleware, where data about the subject and object of access can be extracted from requests. This approach is quite convenient, since it will allow you to delimit areas of responsibility.&lt;/p&gt;

&lt;p&gt;It can be both library (in the form of crates), and custom implementations. But at the moment, the preference is often given to own implementations, which is probably due to the small number of production-ready solutions and the specifics of the applied policies in various projects.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://github.com/casbin/casbin-rs" rel="noopener noreferrer"&gt;casbin-rs&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;
    &lt;a href="https://github.com/casbin/casbin-rs" rel="noopener noreferrer"&gt;
        &lt;img alt="casbin-rs" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faajqjgvqnqy76sfxx2w2.png"&gt;
    &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgii3fx7bmatdzsrtc1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgii3fx7bmatdzsrtc1l.png" alt="casbin badges"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most complete production-ready open source solution that I have been able to find is the adaptation of Casbin (&lt;code&gt;casbin-rs&lt;/code&gt;), with an impressive number of supported access models (&lt;em&gt;ACL, RBAC, ABAC&lt;/em&gt; declared) and the ability to flexibly change policy by changing only the configuration file ...&lt;/p&gt;

&lt;p&gt;Casbin uses its own meta-model &lt;em&gt;PERM (Policy, Effect, Request, Matchers)&lt;/em&gt; to build an access model, which gives more flexibility, but introduces the cost of its interpretation and validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# Request definition
&lt;/span&gt;&lt;span class="nn"&gt;[request_definition]&lt;/span&gt;
&lt;span class="py"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;sub, obj, act&lt;/span&gt;

&lt;span class="c"&gt;# Policy definition
&lt;/span&gt;&lt;span class="nn"&gt;[policy_definition]&lt;/span&gt;
&lt;span class="py"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;sub, obj, act&lt;/span&gt;

&lt;span class="c"&gt;# Policy effect
&lt;/span&gt;&lt;span class="nn"&gt;[policy_effect]&lt;/span&gt;
&lt;span class="py"&gt;e&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;some(where (p.eft == allow))&lt;/span&gt;

&lt;span class="c"&gt;# Matchers
&lt;/span&gt;&lt;span class="nn"&gt;[matchers]&lt;/span&gt;
&lt;span class="py"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;r.sub == p.sub &amp;amp;&amp;amp; r.obj == p.obj &amp;amp;&amp;amp; r.act == p.act&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When describing it, you can easily make a mistake, and therefore the &lt;a href="https://casbin.org/editor/" rel="noopener noreferrer"&gt;web editor of models&lt;/a&gt; was developed for convenient and correct modification.&lt;/p&gt;

&lt;p&gt;The administration of privileges for your system occurs through the description of the policy (in a file or database) corresponding to the PERM model format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p, alice, data1, read
p, bob, data2, write
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this causes a certain duplication of object and subject identifiers and is not obvious at the level of the calling code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;casbin&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Enforcer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"examples/acl_model.conf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"examples/acl_policy.csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.enable_log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the user that wants to access a resource.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"data1"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the resource that is going to be accessed.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// the operation that the user performs on the resource.&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorized&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="nf"&gt;.enforce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;act&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="n"&gt;authorized&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// permit alice to read data1&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// deny the request&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// error occurs&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;Such a tool definitely deserves respect. Many thanks to the community for contributing to its development 👏&lt;/p&gt;

&lt;p&gt;But, as we can see, developers take into account certain nuances and sometimes want to write their own solutions from project to project, since the requirements can be defined initially, and all the flexibility provided by the library may not be needed, and therefore, we can choose a narrower and lighter solution. that meets our requirements.&lt;/p&gt;

&lt;p&gt;As it was with me when I started writing a backend in Rust. The PBAC model was enough for me, and based on my experience in developing web applications, in most typical projects, the &lt;em&gt;ACL&lt;/em&gt;/&lt;em&gt;RBAC&lt;/em&gt; models are enough.&lt;/p&gt;

&lt;p&gt;I came up with the idea of implementing my own solution as a separate open source crate: &lt;em&gt;actix-web-grants&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://github.com/DDtKey/actix-web-grants" rel="noopener noreferrer"&gt;actix-web-grants&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;
    &lt;a href="https://github.com/DDtKey/actix-web-grants" rel="noopener noreferrer"&gt;
        &lt;img alt="actix-web-grants" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94wfabr7z24i6jl2qo4z.png"&gt;
    &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8t9uf5azdyae1zcek2z9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8t9uf5azdyae1zcek2z9.png" alt="actix-web-grants badges"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main idea of the project is to use built-in middleware to get user privileges from a request and specify the necessary permissions directly on your endpoints.&lt;/p&gt;

&lt;p&gt;This is a fairly lightweight crate with simple integration, using which you can at least apply the following models: access lists (ACL), role-based or permission-based access control (&lt;em&gt;RBAC&lt;/em&gt;/&lt;em&gt;PBAC&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Thus, we just need to implement the function of obtaining privileges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sample application with grant protection based on extracting by your custom function&lt;/span&gt;
&lt;span class="nd"&gt;#[actix_web::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;HttpServer&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;GrantsMiddleware&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_extractor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nn"&gt;App&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="nf"&gt;.bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost:8081"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
    &lt;span class="nf"&gt;.run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;.await&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ServiceRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Here is a place for your code to get user permissions/grants/permissions from a request&lt;/span&gt;
    &lt;span class="c1"&gt;// For example from a token or database&lt;/span&gt;

    &lt;span class="c1"&gt;// Stub example&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ROLE_ADMIN&lt;/span&gt;&lt;span class="nf"&gt;.to_string&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;This approach adds flexibility and allows us to implement authorization regardless of the methods of authentication and storage of user privileges: it can be a &lt;em&gt;JWT token&lt;/em&gt;, a &lt;em&gt;database&lt;/em&gt;, an &lt;em&gt;intermediate cache&lt;/em&gt;, or &lt;em&gt;any other solution&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then we can place restrictions directly on our resources (via macro):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;actix_web_grants&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;proc_macro&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;has_roles&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[get(&lt;/span&gt;&lt;span class="s"&gt;"/secure"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="nd"&gt;#[has_roles(&lt;/span&gt;&lt;span class="s"&gt;"ROLE_ADMIN"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;macro_secured&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;HttpResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;HttpResponse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ADMIN_RESPONSE"&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;The ability to change to access policy directly in the code is a distinctive part of &lt;em&gt;actix-web-grants&lt;/em&gt;, reducing duplication of access objects and providing us with visual information about the required privileges.&lt;/p&gt;

&lt;p&gt;For the sake of completeness, minimal examples of applications with an identical usage profile were written and the performance of the authorization process was measured (based on &lt;a href="https://github.com/wg/wrk" rel="noopener noreferrer"&gt;wrk&lt;/a&gt;) to satisfy our own interest.&lt;/p&gt;

&lt;p&gt;The examples are written with a simplified implementation of the RBAC model for two test cases of authorization: a request to a resource is allowed and denied, in accordance with the presence of the necessary roles. Stubs were used for authentication. All code is available on GitHub: &lt;em&gt;&lt;a href="https://github.com/DDtKey/actix-web-authz-benchmark" rel="noopener noreferrer"&gt;actix-web-authz-benchmark&lt;/a&gt;&lt;/em&gt; (more examples can always be found on the pages of these projects).&lt;/p&gt;

&lt;p&gt;The benchmark results can be seen in the table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
   &lt;tr&gt;
       &lt;td rowspan="2"&gt;Benchmark&lt;/td&gt;
       &lt;td colspan="2"&gt;&lt;strong&gt;casbin-rs&lt;/strong&gt;&lt;/td&gt;
       &lt;td colspan="2"&gt;&lt;strong&gt;actix-web-grants&lt;/strong&gt;&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Latency&lt;/td&gt;
   &lt;td&gt;Req/Sec&lt;/td&gt;
   &lt;td&gt;Latency&lt;/td&gt;
   &lt;td&gt;Req/Sec&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Allowed Endpoint&lt;/td&gt;
   &lt;td&gt;6.18 ms&lt;/td&gt;
   &lt;td&gt;16.27k&lt;/td&gt;
   &lt;td&gt;4.41 ms&lt;/td&gt;
   &lt;td&gt;22.69k&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td&gt;Denied Endpoint&lt;/td&gt;
   &lt;td&gt;6.70 ms&lt;/td&gt;
   &lt;td&gt;14.98k&lt;/td&gt;
   &lt;td&gt;4.94 ms&lt;/td&gt;
   &lt;td&gt;20.23k&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;rustc: v1.52.0 (stable); CPU: 2,6 GHz 6-Core Intel Core i7; RAM: 16 GB&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thus, we see that &lt;a href="https://github.com/DDtKey/actix-web-grants" rel="noopener noreferrer"&gt;actix-web-grants&lt;/a&gt; makes it easier to integrate and administer access policies over endpoints (endpoints), while not inferior in performance compared to &lt;a href="https://github.com/casbin/casbin-rs" rel="noopener noreferrer"&gt;casbin-rs&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Post Scriptum
&lt;/h4&gt;

&lt;p&gt;This library does not yet have integrations with many web frameworks in its arsenal, but I have plans to introduce some abstractions and write modules for other frameworks, make some improvements (for example, the ability to inherit roles and support custom types). Any suggestions and contributions will be welcome!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>security</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
