<p dir="auto">Commas (",") and pluses ("+") are legal characters in path segment of the URL so I think Symfony\Component\Routing\Generator\UrlGenerator should not escape them.</p>
<p dir="auto">Currently due to escaping:</p>
<ul dir="auto">
<li><strong>correct route doesn't match when the "requirements" regex contains these characters (it's a bug)</strong></li>
<li>bad looking url shows up in the user browser address bar</li>
<li>this can lead to duplicate content issues with search engines</li>
</ul>
<p dir="auto">Example use case:</p>
<p dir="auto">route:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="category_with_params:
    pattern:        /{category}/{params}/
    defaults:       { _controller: CompanyProjectBundle:Category:show }
    requirements:   { params: &quot;[0-9a-z-]+(,[0-9a-z-]+)+(/[0-9a-z-]+(,[0-9a-z-]+)+)*&quot; }"><pre class="notranslate"><code class="notranslate">category_with_params:
    pattern:        /{category}/{params}/
    defaults:       { _controller: CompanyProjectBundle:Category:show }
    requirements:   { params: "[0-9a-z-]+(,[0-9a-z-]+)+(/[0-9a-z-]+(,[0-9a-z-]+)+)*" }
</code></pre></div>
<p dir="auto">passed values:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="category = laptops
params = brand,acer"><pre class="notranslate"><code class="notranslate">category = laptops
params = brand,acer
</code></pre></div>
<p dir="auto">expected path:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" /laptops/brand,acer/"><pre class="notranslate"><code class="notranslate"> /laptops/brand,acer/
</code></pre></div>
<p dir="auto">generated path:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content=" /laptops/brand%2Cacer/"><pre class="notranslate"><code class="notranslate"> /laptops/brand%2Cacer/
</code></pre></div>
<p dir="auto">following generated path doesn't match "category_with_params" route and produces error (if no other matching routes exists):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="No route found for &quot;GET /laptops/brand%2Cacer/&quot; "><pre class="notranslate"><code class="notranslate">No route found for "GET /laptops/brand%2Cacer/" 
</code></pre></div>
<hr>
<p dir="auto">Possible fix:</p>
<p dir="auto">Replace 115 line in Symfony\Component\Routing\Generator\UrlGenerator:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="                    $url = $token[1].str_replace('%2F', '/', urlencode($tparams[$token[3]])).$url;"><pre class="notranslate"><code class="notranslate">                    $url = $token[1].str_replace('%2F', '/', urlencode($tparams[$token[3]])).$url;
</code></pre></div>
<p dir="auto">with</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="                    $url = $token[1].str_replace(
                        array('%2F', '%2B', '%2C'),
                        array('/',   '+',   ','),
                        urlencode($tparams[$token[3]])
                    ).$url;"><pre class="notranslate"><code class="notranslate">                    $url = $token[1].str_replace(
                        array('%2F', '%2B', '%2C'),
                        array('/',   '+',   ','),
                        urlencode($tparams[$token[3]])
                    ).$url;
</code></pre></div>
<p dir="auto"><strong>Description</strong><br>
2FA shoud be natively supported by the security component, to get more interoperability between projects and support from the community (as well as external bundles provinding specific 2FA features, e.g. U2F).</p>
<p dir="auto">There are bundles providing support, but most of them are either outdated or not providing a simple, low level API (with a seamless integration in the Symfony security component). They also do not provide the same guaranteed support as Symfony does.</p>
<p dir="auto"><strong>Example</strong><br>
The latest version of <code class="notranslate">scheb/two-factor-bundle</code> provides a good proof of concept, but the API is too restrictive, high level and some of the validation / handling code for the 2FA is a duplicate from existing code in the security component.</p>
<p dir="auto">Some of the main low levels features which would be useful:</p>
<ul dir="auto">
<li>Providers/Challengers: used to implement a <em>way</em> for validating 2FA</li>
<li>Activators: used to enable/disabled 2FA for specific providers based on the authentication context</li>
<li>SecondFactorInterface, which may be used to persist challenges (same use as the UserInterface, but for 2FA)</li>
</ul>
<p dir="auto">I guess a new role equivalent to IS_AUTHENTICATED_ANONYMOUSLY would be required, like in the process described here: <a href="https://github.com/scheb/two-factor-bundle/blob/master/Resources/doc/index.md#the-authentication-process">https://github.com/scheb/two-factor-bundle/blob/master/Resources/doc/index.md#the-authentication-process</a></p>
<p dir="auto">[Edit] See this comment for a proposal to unify sudo mode, MFA and remember me:</p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="369943418" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/28868" data-hovercard-type="issue" data-hovercard-url="/symfony/symfony/issues/28868/hovercard?comment_id=536877013&amp;comment_type=issue_comment" href="https://github.com/symfony/symfony/issues/28868#issuecomment-536877013">#28868 (comment)</a></li>
</ul>