lemonldap-ng/doc/pages/documentation/current/applications/symfony.html
2019-09-23 22:41:16 +02:00

267 lines
16 KiB
HTML

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" />
<title>documentation:2.0:applications:symfony</title>
<meta name="generator" content="DokuWiki"/>
<meta name="robots" content="index,follow"/>
<meta name="keywords" content="documentation,2.0,applications,symfony"/>
<link rel="search" type="application/opensearchdescription+xml" href="../lib/exe/opensearch.html" title="LemonLDAP::NG"/>
<link rel="start" href="symfony.html"/>
<link rel="contents" href="symfony.html" title="Sitemap"/>
<link rel="stylesheet" type="text/css" href="../lib/exe/css.php.t.bootstrap3.css"/>
<!-- //if:usedebianlibs
<link rel="stylesheet" type="text/css" href="/javascript/bootstrap/css/bootstrap.min.css" />
//elsif:useexternallibs
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"></script>
//elsif:cssminified
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.min.css" />
//else -->
<link rel="stylesheet" type="text/css" href="/static/bwr/bootstrap/dist/css/bootstrap.css" />
<!-- //endif -->
<script type="text/javascript">/*<![CDATA[*/var NS='documentation:2.0:applications';var JSINFO = {"id":"documentation:2.0:applications:symfony","namespace":"documentation:2.0:applications"};
/*!]]>*/</script>
<script type="text/javascript" charset="utf-8" src="../lib/exe/js.php.t.bootstrap3.js"></script>
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery/jquery.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery/dist/jquery.js"></script>
<!-- //endif -->
<!-- //if:usedebianlibs
<script type="text/javascript" src="/javascript/jquery-ui/jquery-ui.min.js"></script>
//elsif:useexternallibs
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
//elsif:jsminified
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.min.js"></script>
//else -->
<script type="text/javascript" src="/static/bwr/jquery-ui/jquery-ui.js"></script>
<!-- //endif -->
</head>
<body>
<div class="dokuwiki export container">
<!-- TOC START -->
<div id="dw__toc">
<h3 class="toggle">Table of Contents</h3>
<div>
<ul class="toc">
<li class="level1"><div class="li"><a href="#presentation">Presentation</a></div></li>
<li class="level1"><div class="li"><a href="#configuration">Configuration</a></div></li>
<li class="level1"><div class="li"><a href="#references">References</a></div></li>
</ul>
</div>
</div>
<!-- TOC END -->
<h1 class="sectionedit1" id="php_symfony">PHP (Symfony)</h1>
<div class="level1">
<p>
<a href="symfony_logo.png_documentation_2.0_applications_symfony.html" class="media" title="applications:symfony_logo.png"><img src="symfony_logo.png" class="mediacenter" alt="" /></a>
</p>
</div>
<!-- EDIT1 SECTION "PHP (Symfony)" [1-69] -->
<h2 class="sectionedit2" id="presentation">Presentation</h2>
<div class="level2">
<p>
<a href="https://symfony.com/" class="urlextern" title="https://symfony.com/" rel="nofollow">Symfony</a> is the well-known PHP framework. It is intended to ease the development of PHP applications.
</p>
<p>
Symfony provides many methods conventions to authenticate users (basic, ldap,...) and to load external user sources (ldap, database). The method presented here relies on the &quot;remote_user&quot; method. (in security firewall)
</p>
</div>
<!-- EDIT2 SECTION "Presentation" [70-443] -->
<h2 class="sectionedit3" id="configuration">Configuration</h2>
<div class="level2">
<p>
Follow these step to protect your application using the &quot;REMOTE_USER&quot; HTTP header.
</p>
<p>
1. Adapt the app/config/security.yml configuration file as below:
</p>
<pre class="code file json">security:
&nbsp;
encoders:
AppBundle\Security\User\HeaderUser: plaintext
&nbsp;
providers:
header:
id: AppBundle\Security\User\HeaderUserProvider
&nbsp;
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
&nbsp;
main:
pattern: ^/
remote_user:
user: HTTP_REMOTE_USER
provider: header</pre>
<ul>
<li class="level1"><div class="li"> encoders : define a password hashing scheme (useless in our case, but the parameter is mandatory)</div>
</li>
<li class="level1"><div class="li"> providers : define the user providers (even virtual)</div>
</li>
<li class="level1"><div class="li"> remote_user : define the authentication method to &quot;assume the user is already authenticated and get an http variable to know his username&quot;</div>
</li>
<li class="level1"><div class="li"> user : define the HTTP header containing the username</div>
</li>
<li class="level1"><div class="li"> provider : references the previously defined provider owning the user data (in our scenario, a virtual)</div>
</li>
</ul>
<p>
2. Define a &quot;header user&quot; class
</p>
<p>
Create the file src/AppBundle/Security/User/HeaderUser.php :
</p>
<pre class="code file php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="co1">// src/Security/User/HeaderUser.php</span>
<span class="kw2">namespace</span> AppBundle\Security\User<span class="sy0">;</span>
&nbsp;
<span class="kw2">use</span> Symfony\Component\Security\Core\User\UserInterface<span class="sy0">;</span>
<span class="kw2">use</span> Symfony\Component\Security\Core\User\EquatableInterface<span class="sy0">;</span>
&nbsp;
<span class="kw2">class</span> HeaderUser implements UserInterface<span class="sy0">,</span> EquatableInterface
<span class="br0">&#123;</span>
<span class="kw2">private</span> <span class="re0">$username</span><span class="sy0">;</span>
<span class="kw2">private</span> <span class="re0">$password</span><span class="sy0">;</span>
<span class="kw2">private</span> <span class="re0">$salt</span><span class="sy0">;</span>
<span class="kw2">private</span> <span class="re0">$roles</span><span class="sy0">;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span><span class="re0">$username</span><span class="sy0">,</span> <span class="re0">$password</span><span class="sy0">,</span> <span class="re0">$salt</span><span class="sy0">,</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="re0">$roles</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">username</span> <span class="sy0">=</span> <span class="re0">$username</span><span class="sy0">;</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">password</span> <span class="sy0">=</span> <span class="re0">$password</span><span class="sy0">;</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">salt</span> <span class="sy0">=</span> <span class="re0">$salt</span><span class="sy0">;</span>
<span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">roles</span> <span class="sy0">=</span> <span class="re0">$roles</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> getRoles<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">roles</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> getPassword<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">password</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> getSalt<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">salt</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="kw2">public</span> <span class="kw2">function</span> getUsername<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">username</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> eraseCredentials<span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> isEqualTo<span class="br0">&#40;</span>UserInterface <span class="re0">$user</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$user</span> instanceof HeaderUser<span class="br0">&#41;</span> <span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">username</span> <span class="sy0">!==</span> <span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">getUsername</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
<span class="kw1">return</span> <span class="kw4">false</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="co1">//if ($this-&gt;password !== $user-&gt;getPassword()) {</span>
<span class="co1">// return false;</span>
<span class="co1">//}</span>
&nbsp;
<span class="kw1">return</span> <span class="kw4">true</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="br0">&#125;</span>
<span class="sy1">?&gt;</span></pre>
<p>
3. Define a &quot;header user provider&quot; class relying on the previous class
</p>
<p>
Create the file src/AppBundle/Security/User/HeaderUserProvider.php :
</p>
<pre class="code file php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="co1">// src/Security/User/HeaderUserProvider.php</span>
<span class="kw2">namespace</span> AppBundle\Security\User<span class="sy0">;</span>
&nbsp;
<span class="kw2">use</span> AppBundle\Security\User\HeaderUser<span class="sy0">;</span>
<span class="kw2">use</span> Symfony\Component\Security\Core\User\UserProviderInterface<span class="sy0">;</span>
<span class="kw2">use</span> Symfony\Component\Security\Core\User\UserInterface<span class="sy0">;</span>
<span class="kw2">use</span> Symfony\Component\Security\Core\Exception\UsernameNotFoundException<span class="sy0">;</span>
<span class="kw2">use</span> Symfony\Component\Security\Core\Exception\UnsupportedUserException<span class="sy0">;</span>
&nbsp;
<span class="kw2">class</span> HeaderUserProvider implements UserProviderInterface
<span class="br0">&#123;</span>
<span class="kw2">public</span> <span class="kw2">function</span> loadUserByUsername<span class="br0">&#40;</span><span class="re0">$username</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$username</span><span class="br0">&#41;</span> <span class="br0">&#123;</span>
&nbsp;
<span class="re0">$password</span> <span class="sy0">=</span> <span class="st0">&quot;dummy&quot;</span><span class="sy0">;</span>
<span class="re0">$salt</span> <span class="sy0">=</span> <span class="st0">&quot;&quot;</span><span class="sy0">;</span>
<span class="re0">$roles</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st_h">'ROLE_USER'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp;
<span class="kw1">return</span> <span class="kw2">new</span> HeaderUser<span class="br0">&#40;</span><span class="re0">$username</span><span class="sy0">,</span> <span class="re0">$password</span><span class="sy0">,</span> <span class="re0">$salt</span><span class="sy0">,</span> <span class="re0">$roles</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">throw</span> <span class="kw2">new</span> UsernameNotFoundException<span class="br0">&#40;</span>
<a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st_h">'Username &quot;%s&quot; does not exist.'</span><span class="sy0">,</span> <span class="re0">$username</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> refreshUser<span class="br0">&#40;</span>UserInterface <span class="re0">$user</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$user</span> instanceof HeaderUser<span class="br0">&#41;</span> <span class="br0">&#123;</span>
<span class="kw1">throw</span> <span class="kw2">new</span> UnsupportedUserException<span class="br0">&#40;</span>
<a href="http://www.php.net/sprintf"><span class="kw3">sprintf</span></a><span class="br0">&#40;</span><span class="st_h">'Instances of &quot;%s&quot; are not supported.'</span><span class="sy0">,</span> <a href="http://www.php.net/get_class"><span class="kw3">get_class</span></a><span class="br0">&#40;</span><span class="re0">$user</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
<span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">loadUserByUsername</span><span class="br0">&#40;</span><span class="re0">$user</span><span class="sy0">-&gt;</span><span class="me1">getUsername</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="kw2">public</span> <span class="kw2">function</span> supportsClass<span class="br0">&#40;</span><span class="re0">$class</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
<span class="kw1">return</span> HeaderUser<span class="sy0">::</span><span class="kw2">class</span> <span class="sy0">===</span> <span class="re0">$class</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="sy1">?&gt;</span></pre>
</div>
<!-- EDIT3 SECTION "Configuration" [444-4373] -->
<h2 class="sectionedit4" id="references">References</h2>
<div class="level2">
<ul>
<li class="level1"><div class="li"> <a href="http://symfony.com/doc/current/security/pre_authenticated.html#remote-user-based-authentication" class="urlextern" title="http://symfony.com/doc/current/security/pre_authenticated.html#remote-user-based-authentication" rel="nofollow">http://symfony.com/doc/current/security/pre_authenticated.html#remote-user-based-authentication</a></div>
</li>
<li class="level1"><div class="li"> <a href="https://symfony.com/doc/current/security/custom_provider.html" class="urlextern" title="https://symfony.com/doc/current/security/custom_provider.html" rel="nofollow">https://symfony.com/doc/current/security/custom_provider.html</a></div>
</li>
</ul>
</div>
<!-- EDIT4 SECTION "References" [4374-] --></div>
</body>
</html>