title: Symfony2 using http-basic and preauthentication together
body: <h3>What do I need</h3>
  
  <p>In my application I have a following schema</p>
  
  <pre><code>users (id(PK), username, email(unique), password, etc)
  devices (id(PK), device_id, status, user_id)
  </code></pre>
  
  <p>Relation</p>
  
  <pre><code>user HAS ONE device
  </code></pre>
  
  <p>The application needs to support basic authentication in two variations.</p>
  
  <ul>
  <li><strong>Variation one</strong>: Normal, <strong>email as username and password</strong>. This approach will be used by the admin console. The admin console just like an webapp.</li>
  <li><strong>Variation two</strong>: email as username, <strong>device id as password</strong>. This approach will be used by mobile application. During the authentication process from device, it will pass the device id as password. Since a user will have only device at a time, the authentication process will match the device id and email to identify the user.</li>
  </ul>
  
  <h3>What I tried?</h3>
  
  <p>I have basically followed <a href="http://symfony.com/doc/current/cookbook/security/api_key_authentication.html" rel="nofollow">symfony tutorial on api key based authentication</a> for the second variation and <code>http-basic</code> for the first. Please find my security.xml below.</p>
  
  <p>Here, I need the firewall setup to pass when any of the underlying authentication mechanism passes. For instance, in case of web authentication, only http-basic will pass, in case of device login only simple-preauth will pass.</p>
  
  <p><strong>security.xml</strong></p>
  
  <pre><code>&lt;srv:container xmlns="... ..."&gt;
  
    &lt;config&gt;
      &lt;firewall name="resource" pattern="^/" stateless="true"&gt;
          &lt;http-basic realm="Webservice" /&gt;
          &lt;simple-preauth authenticator="device_authenticator" /&gt;
      &lt;/firewall&gt;
  
      &lt;provider name="administrators"&gt;
        &lt;entity class="AppBundle\Entity\User" property="email"/&gt;
      &lt;/provider&gt;
      &lt;provider name="device_id_user_provider" id="device_id_user_provider" /&gt;
  
      &lt;encoder class="AppBundle\Entity\User" algorithm="bcrypt" cost="12"/&gt;
  
    &lt;/config&gt;
  &lt;/srv:container&gt;
  </code></pre>
  
  <p><strong>services.xml</strong></p>
  
  <pre><code>&lt;container xmlns="... ..."&gt;
  
     &lt;services&gt;
         &lt;service id="device_id_user_provider"
                  class="AppBundle\Security\DeviceIdUserProvider"&gt;
             &lt;argument type="service" id="doctrine.orm.entity_manager" /&gt;
         &lt;/service&gt;
         &lt;service id="device_authenticator" class="AppBundle\Security\DeviceAuthenticator"&gt;
              &lt;argument type="service" id="device_id_user_provider" /&gt;
         &lt;/service&gt;
     &lt;/services&gt;
  &lt;/container&gt;
  </code></pre>
  
  <h3>My problem</h3>
  
  <p>For every request the firewall tries to pass both of the authentication mechanisms. Hence its always responding with 401.</p>
  
  <ul>
  <li>Did I set this up in a wrong way? </li>
  <li>Or a firewall MUST pass all of its underlying auth mechanisms? </li>
  <li>Or this is happening only because of using preauthentication?</li>
  <li>Any recommended approach to achieve this?</li>
  </ul>