title: Spring Security exposing AuthenticationManager without WebSecurityConfigurerAdapter
body: <p>I'm trying incoming Spring Boot 2.7.0-SNAPSHOT, which uses Spring Security 5.7.0, which deprecate <code>WebSecurityConfigurerAdapter</code>.</p>
  <p>I read <a href="https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter" rel="noreferrer">this blog post</a>, but I'm not sure to understand how I can expose the default implementation of <code>AuthenticationManager</code> to my JWT authorization filter.</p>
  <p>The old <code>WebSecurityConfig</code>, using <code>WebSecurityConfigurerAdapter</code> (works fine) :</p>
  <pre class="lang-java prettyprint-override"><code>@Configuration
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  
      @Autowired
      private JWTTokenUtils jwtTokenUtils;
  
      @Bean
      protected AuthenticationManager getAuthenticationManager() throws Exception {
          return authenticationManager();
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
                  // disable CSRF as we do not serve browser clients
                  .csrf().disable()
                  // allow access restriction using request matcher
                  .authorizeRequests()
                  // authenticate requests to GraphQL endpoint
                  .antMatchers(&quot;/graphql&quot;).authenticated()
                  // allow all other requests
                  .anyRequest().permitAll().and()
                  // JWT authorization filter
                  .addFilter(new JWTAuthorizationFilter(getAuthenticationManager(), jwtTokenUtils))
                  // make sure we use stateless session, session will not be used to store user's state
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
      }
  
  }
  </code></pre>
  <p>The new <code>WebSecurityConfig</code> :</p>
  <pre class="lang-java prettyprint-override"><code>@Configuration
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class WebSecurityConfig {
  
      @Autowired
      private JWTTokenUtils jwtTokenUtils;
  
      @Bean
      public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
          final AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
          http
                  // disable CSRF as we do not serve browser clients
                  .csrf().disable()
                  // allow access restriction using request matcher
                  .authorizeRequests()
                  // authenticate requests to GraphQL endpoint
                  .antMatchers(&quot;/graphql&quot;).authenticated()
                  // allow all other requests
                  .anyRequest().permitAll().and()
                  // JWT authorization filter
                  .addFilter(new JWTAuthorizationFilter(authenticationManager, jwtTokenUtils))
                  // make sure we use stateless session, session will not be used to store user's state
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
          return http.build();
      }
  
  }
  </code></pre>
  <p>As you see I have no <code>AuthenticationManager</code> exposed bean anymore. I cannot get it from the <code>WebSecurityConfigurerAdapter</code>. So I tried to get it directly from the <code>HttpSecurity</code> in the <code>filterChain</code> method, so I can pass it to my JWT filter directly.</p>
  <p>But I still need an <code>AuthenticationManager</code> bean to be exposed to my <code>JWTAuthorizationFilter</code> :</p>
  <blockquote>
  <p>Parameter 0 of constructor in com.example.config.security.JWTAuthorizationFilter required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.</p>
  </blockquote>
  <p>How can I expose it?</p>
  <p>Here is the JWT authorization filter (checks the token and authenticate the user, I have a custom <code>UserDetailsService</code> which do the credentials check in the database) :</p>
  <pre class="lang-java prettyprint-override"><code>@Component
  public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
  
      private final JWTTokenUtils jwtTokenUtils;
  
      public JWTAuthorizationFilter(AuthenticationManager authManager, JWTTokenUtils jwtTokenUtils) {
          super(authManager);
          this.jwtTokenUtils = jwtTokenUtils;
      }
  
      @Override
      protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
  
          // retrieve request authorization header
          final String authorizationHeader = req.getHeader(&quot;Authorization&quot;);
  
          // authorization header must be set and start with Bearer
          if (authorizationHeader != null &amp;&amp; authorizationHeader.startsWith(&quot;Bearer &quot;)) {
  
              // decode JWT token
              final JWTTokenPayload jwtTokenPayload = jwtTokenUtils.decodeToken(authorizationHeader);
  
              // if user e-mail has been retrieved correctly from the token and if user is not already authenticated
              if (jwtTokenPayload.getEmail() != null &amp;&amp; SecurityContextHolder.getContext().getAuthentication() == null) {
  
                  // authenticate user
                  final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(jwtTokenPayload.getEmail(), null, Collections.singletonList(jwtTokenPayload.getRole()));
  
                  // set authentication in security context holder
                  SecurityContextHolder.getContext().setAuthentication(authentication);
  
              } else {
                  log.error(&quot;Valid token contains no user info&quot;);
              }
          }
          // no token specified
          else {
              res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
          }
  
          // pass request down the chain, except for OPTIONS requests
          if (!&quot;OPTIONS&quot;.equalsIgnoreCase(req.getMethod())) {
              chain.doFilter(req, res);
          }
  
      }
  
  }
  </code></pre>
  <p>EDIT :</p>
  <p>I realized I can manage to get the <code>authenticationManager</code> in my JWT filter using the method provided <a href="https://github.com/spring-projects/spring-security/issues/10822#issuecomment-1036063319" rel="noreferrer">in this issue</a>, but still I need an <code>AuthenticationManager</code> to be exposed globally because I also need it in my controller.</p>
  <p>Here is the authentication controller which need the <code>authenticationManager</code> to be injected :</p>
  <pre class="lang-java prettyprint-override"><code>@RestController
  @CrossOrigin
  @Component
  public class AuthController {
  
      @Autowired
      private JWTTokenUtils jwtTokenUtils;
  
      @Autowired
      private AuthenticationManager authenticationManager;
  
      @RequestMapping(value = &quot;/authenticate&quot;, method = RequestMethod.POST)
      public ResponseEntity&lt;?&gt; authenticate(@RequestBody JWTRequest userRequest) {
  
          // try to authenticate user using specified credentials
          final Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(userRequest.getEmail(), userRequest.getPassword()));
  
          // if authentication succeeded and is not anonymous
          if (authentication != null &amp;&amp; !(authentication instanceof AnonymousAuthenticationToken) &amp;&amp; authentication.isAuthenticated()) {
  
              // set authentication in security context holder
              SecurityContextHolder.getContext().setAuthentication(authentication);
  
              // get authorities, we should have only one role per member so simply get the first one
              final GrantedAuthority grantedAuthority = authentication.getAuthorities().iterator().next();
  
              // generate new JWT token
              final String jwtToken = jwtTokenUtils.generateToken(authentication.getPrincipal(), grantedAuthority);
  
              // return response containing the JWT token
              return ResponseEntity.ok(new JWTResponse(jwtToken));
          }
  
          return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
  
      }
  
  }
  </code></pre>