Reputation: 2421
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
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
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
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
Reputation: 3543
Lot of problems are there in your code.
(ApplicationContext) authenticationManager()
you can not cast AuthenticationManager to ApplicationContext
.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()
CustomAuthenticationProvider extends BasicAuthenticationFilter
An authentication provider is one which implements AuthenticationProvider
interface. In your case naming should be xxxAuthFilter
.
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 overrideauthenticate()
method and it should returnAuthentication
object(whereAuthentication
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
Reputation: 66
Your error seems to be that the AuthenticationManager
is not present as a Spring Bean.
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();
}
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