Require

Related documentation

The Allow, Deny and Order directives have long been ones that people have found confusing and counterintuitive. And although they could be combined in various ways, using the Satisfy directive, they were still rather limiting. Complex combinations of restrictions were often very difficult.

Among the new features on 2.4 are new Require directives and syntaxes that allow very complex combinations of requirements.

mod_access_compat retains the old Allow, Deny, Order, Satisfy syntax, to ease the transition off of it. However, these directives have been removed from all example configurations, and you’re encouraged to stop using them.

The Require works much like it always has, although new options are added to it to replace the Allow/Deny syntax:

Require all granted
Access is allowed unconditionally.
Require all denied
Access is denied unconditionally.
Require env env-var [env-var]
...
Access is allowed only if one of the given environment variables is
set.
Require method http-method [http-method]
...
Access is allowed only for the given HTTP methods.
Require expr expression
Access is allowed if expression evaluates to true.

The Require expr syntax uses the new expression engine, and so allows for very complex requirements.

Additionally, various other modules can augment the Require syntax with other requirements. For example, mod_authz_host provides access control by IP address:

Require ip 192.168

Other than the Require expr syntax, much of the above is as before, just stated more clearly. But the other directives I want to talk about here give you ways to combine the requirements that were not possible at all before.

The RequireAll directive allows you to combine several requirements and enforce all of them. RequireAny says that any one of the requirements is similar. And RequireNone says that none of the requirements must be true. What’s really powerful about these is that they are containers, and so can be nested within one another to create arbitrarily complex scenarios.

First, a few simple examples:

In the first example, we require that a client be either on our local network, or that they be authenticated with a username and password. Either one is sufficient. That is, if they’re on our local network, they won’t be asked for a password.

<RequireAny>
	Require ip 10.2
	Require valid-user 
</RequireAny>

Alternately, we could require both – that they be on our local network and that they provode a password:

<RequireAll>
	Require ip 10.2
	Require valid-user 
</RequireAll> 

Finally, we could require that we won’t permit any access from someone who’s on our local network, or who is logged in.

<RequireNone>
	Require ip 10.2
	Require valid-user 
</RequireNone>

This gets really interesting when you want to enforce several different kinds of access control in different ways:

<RequireAll>
  <RequireAny>
    Require user superadmin
    <RequireAll>
      Require group admins
      Require ldap-group cn=Administrators,o=Airius
      <RequireAny>
        Require group sales
        Require ldap-attribute dept="sales"
      </RequireAny>
    </RequireAll>
  </RequireAny>
  <RequireNone>
    Require group temps
    Require ldap-group cn=Temporary Employees,o=Airius
  </RequireNone>
</RequireAll>

As you can see, we’ve combined several different sets of requirements to ensure that the user is in the sales or admin group, isn’t a temporary employee, and various other combinations.

As with other features that are new in 2.4, you’ll start to see more and more examples of their use as time goes by. We hope that this has given you a taste of what the new syntax makes possible that was difficult, or even impossible, before.

<If>, <IfElse>, and <Else>

Over the coming weeks, I’m going to be writing several articles about new features in Apache httpd 2.4. To me the most compelling reason to upgrade to Apache 2.4 today is the <If> directive, so that’s where I’ll start.

Related documentation:

This is something that people have been asking for since the very first day I was involved in Apache stuff – the ability to insert conditional statements in configuration files. And now that it’s here, it’s everything we wanted. Even a bit more.

The <If> directive may be used in all contexts (server config, virtual host, directory, .htaccess) and is evaluated at request time to effect the behavior of the server.

Some of the things you might use this directive for, you’ve been using mod_rewrite for up until now, so one of the side-effects of this directive is that we can reduce our reliance on mod_rewrite’s complex syntax for common situations. Over the coming months, more examples will be added to the documentation, and we’ll have a recipe section with many of the same sorts of scenarios that are in the mod_rewrite recipe section.

Let’s start with a few simple examples so that you can see how it might be used. Consider a case where you have a website, www.wooga.com, and you want to compel people to use the www prefix for all requests. In the distant past, you may have used mod_rewrite for this, but here it is stated more clearly with the If directive:

<If "$req{Host} != 'www.wooga.com'">
    RedirectMatch (.*) http://www.wooga.com$1
</If>

In plain language, that says "if the host request header isn’t www.wooga.com, redirect the request to www.wooga.com."

In fact, most of the commonest uses of mod_rewrite can now be replaced with the If directive, making them easier to read, and, therefore, less prone to error, and the redirect looping that so often plagues RewriteRule-based solutions.

For more complex scenarios, there’s also <ElseIf> and <Else> directives, so that you can create multi-step if … elseif … elseif … else logic flows in your configuration files.

These directives may be used in any scope – main configuration, virtual hosts, directories, or .htaccess files – and so give you significantly more power for conditional configurations than you ever had before.

The term in the If statement can be any request header ($req) or environment variable ($env), or many other values. Expressions in these comparisons can be fairly complicated, as they can use the new expression syntax which is another major enhancements in httpd 2.4, and an article for another day.

As with many features that are brand new in 2.4, you can expect more detailed official documentation in the near future, complete with many examples. For now, I’d encourage you to study the expression syntax documentation, and experiment.