 <p>I believe that the problem is in the <strong>order</strong> of your rules:</p> <pre><code>.antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/admin/login").permitAll() </code></pre> <p>The order of the rules matters and the more specific rules should go first. Now everything that starts with <code>/admin</code> will require authenticated user with ADMIN role, even the <code>/admin/login</code> path (because <code>/admin/login</code> is already matched by the <code>/admin/**</code> rule and therefore the second rule is ignored).</p> <p>The rule for the login page should therefore go before the <code>/admin/**</code> rule. E.G.</p> <pre><code>.antMatchers("/admin/login").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") </code></pre>