Mr.DevEng
Mr.DevEng

Reputation: 2421

Required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found. message from spring security

I am trying to implement one sample demo for Spring Security with Spring Boot for checking the authentication. I am trying to implement a basic workout for Spring Security and getting the following message,

Description:

Parameter 0 of constructor in com.spacestudy.service.CustomAuthenticationProvider required a bean of type 'org.springframework.security.authentication.AuthenticationManager' that could not be found.

Action:

Consider defining a bean of type 'org.springframework.security.web.AuthenticationEntryPoint' in your configuration.

My security config class SecurityConfig.java,

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
private AuthenticationEntryPoint authEntryPoint;

 @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .addFilter(new ApplicationContextHeaderFilter((ApplicationContext) authenticationManager()));
    }
}

And my BasicAuthenticationFilter implementation like the following,

@Component
public class  CustomAuthenticationProvider  extends  BasicAuthenticationFilter    { 

public CustomAuthenticationProvider(AuthenticationManager authenticationManager) {
    super(authenticationManager);
    // TODO Auto-generated constructor stub
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
    SecurityContextHolder.getContext().setAuthentication(authentication);
    filterChain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
   String bearerToken = request.getHeader("accessToken");
String username = "test";
String password = "test";
    if (username != null && !username.isEmpty()) {
        return new UsernamePasswordAuthenticationToken(username, null, null);
      }
    return null;
    }
 }

How can I resolve this issue?

Upvotes: 2

Views: 17190

Answers (5)

Ashikur Rahman Rashid
Ashikur Rahman Rashid

Reputation: 182

Create a new java class. And Configure like below:

@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }
}

Upvotes: 0

LongDev
LongDev

Reputation: 221

You can try on this, put it in config security file

 @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

Upvotes: 2

Matej Janotka
Matej Janotka

Reputation: 332

I am not sure but shoudn't the CustomAuthenticationProvider implement AuthenticationProvider and AuthenticationManager is just a container for authentication providers and it seems that you dont have any.

Check this site for more info https://www.baeldung.com/spring-security-authentication-provider

Upvotes: 0

PraveenKumar Lalasangi
PraveenKumar Lalasangi

Reputation: 3543

Lot of problems are there in your code.

  1. (ApplicationContext) authenticationManager()
    you can not cast AuthenticationManager to ApplicationContext

  2. .addFilter(new ApplicationContextHeaderFilter(...))
    I don't know Why you are using ApplicationContextHeaderFilter for simple demo application.

    • You should have preferred BasicAuthenticationFilter or even simple default configuration provided for HttpSecurity with .httpBasic()

    • You should have preferred UsernamePasswordAuthenticationFilter or even simple default configuration provided in HttpSecurity with .formLogin()

  3. CustomAuthenticationProvider extends BasicAuthenticationFilter
    An authentication provider is one which implements AuthenticationProvider interface. In your case naming should be xxxAuthFilter.

  4. You have done nothing in below code.(got existing authentication object and set it back without creating an valid authentication object.)

UsernamePasswordAuthenticationToken authentication = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authentication);

Coming to the AuthenticationManager and AuthFilters implementation point of view,
For add filter you can add any implementation of Spring Security provided filters as given below
.addFilter(AnyFilterImplementationFromThisLink) (But not all filters are auth filters. Where auth filters will attempt to authenticate with the authenticationManager configured) For example If you consider UsernamePasswordAuthenticationFilter or BasicAuthenticationFilter

you should take care of setting AuthenticationManager where your auth manager should override authenticate() method and it should return Authentication object(where Authentication object will have auth principal, credentials and granted authorities list)

Or

If you don't want to implement authentication manager...
In simple way in your filters(implementation of OncePerRequestFilter) doFilterInternal() method set the `Authentication` object in `SecurityContext`
List<GrantedAuthority> authorityList = new ArrayList<>();
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
authorityList.add(authority);
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, authorityList);
//Note UsernamePasswordAuthenticationToken implements Authentication
SecurityContextHolder.getContext().setAuthentication(authToken);

How any auth filter works is if there is a valid Authentication object then filter chain will continue without attempting authentication otherwise it will attemptAuthentication by overrided attemptAuthentication() method.
But your ApplicationContextHeaderFilter is a implementation of OncePerRequestFilter where it has no attemptAuthentication() and i don't know the order of ApplicationContextHeaderFilter if it's order is after creating security context then you can set the authentication object to security context.

Upvotes: 1

Christophe Mohimont
Christophe Mohimont

Reputation: 66

Your error seems to be that the AuthenticationManager is not present as a Spring Bean.

Option 1

Register an AuthenticationManager in Spring Bean. All is provided by Spring for do this directly in your SecurityConfig class by overriding the WebSecurityConfigurerAdapter#authenticationManagerBean method like explain in the documentation of it

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

Option 2

Avoid to register an AuthenticationManager in Spring, but directly your CustomAuthenticationProvider classs.

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public CustomAuthenticationProvider authenticationProvider() throws Exception {
        return new CustomAuthenticationProvider(authenticationManager());
    }
}

Don't forget to remove the @Component annotation on the CustomAuthenticationProvider class with this method.

Upvotes: 0

Related Questions