Spring Security 3.2: #Autowire doesn't work with java configuration and custom AuthenticationProvider in Spring MVC application? - spring

This problem is relatively well discussed in several blog posts and SO questions. Nevertheless, I wasn't able to find one specifically addressing the problem with java configuration. I'm suspecting that I'm doing something wrong in my java configuration files, since I've found some posts indicating that the problem can be resolved by removing the debug XML tag (https://jira.springsource.org/browse/SEC-1885).
I'm using 3.2.0.RELEASE of spring security, and 3.2.6.RELEASE of spring framework. Below the main files used in the spring security/mvc configuration and the custom AuthenticationProvider.
WebConfig:
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.mypackage"})
#ImportResource( { "classpath:/spring-data.xml", "classpath:/trace-context.xml" })
#EnableTransactionManagement
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
#Bean
public StandardServletMultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
#Bean(destroyMethod = "shutdown")
public GraphDatabaseService graphDatabaseService() {
return new GraphDatabaseFactory().newEmbeddedDatabase("target/temp.db");
}
#Bean
public RepositoryInitializer repositoryInitializer() {
return new RepositoryInitializer();
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
#Bean
public LocaleResolver localeResolver() {
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
return cookieLocaleResolver;
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasenames("classpath:messages/messages", "classpath:messages/validation");
// if true, the key of the message will be displayed if the key is not
// found, instead of throwing a NoSuchMessageException
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultEncoding("UTF-8");
// # -1 : never reload, 0 always reload
messageSource.setCacheSeconds(0);
return messageSource;
}
}
WebInitializer:
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
return new Filter[] { characterEncodingFilter, new SiteMeshFilter()};
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
//servletContext.addListener(new HttpSessionEventPublisher());
}
}
WebSecurityConfig:
#Configuration
#EnableWebSecurity
#Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().permitAll();
// .antMatchers("/", "/login").permitAll()
// .anyRequest().authenticated();
http
.formLogin()
.defaultSuccessUrl("/hello")
.loginPage("/login")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.permitAll();
http
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**");
}
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder.authenticationProvider(new ApplicationAuthenticationProvider());
}
}
WebSecurityInitializer:
public class WebSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
AuthenticationProvider:
#Component(value = "authenticationProvider")
public class ApplicationAuthenticationProvider implements AuthenticationProvider {
#Autowired
public UserService userService;
public ApplicationAuthenticationProvider() {}
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
User user = userService.loadUserByUsername(username);
if (user == null) {
throw new BadCredentialsException("Username not found.");
}
if (!password.equals(user.getPassword())) {
throw new BadCredentialsException("Wrong password.");
}
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return new UsernamePasswordAuthenticationToken(username, password, authorities);
}
#Override
public boolean supports(Class<?> arg0) {
return true;
}
}
UserService:
#Service
public class UserService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public User loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByUsername(username);
}
}
Spring is throwing an exception while it is building its application context (during application initialization):
[ERROR] [main 11:53:37] (FrameworkServlet.java:initServletBean:467) Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authenticationProvider': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.evidencefactory.service.UserService com.evidencefactory.security.ApplicationAuthenticationProvider.userService; nested exception is java.lang.IllegalArgumentException: Can not set com.evidencefactory.service.UserService field com.evidencefactory.security.ApplicationAuthenticationProvider.userService to sun.proxy.$Proxy71
I don't understand why it is happening, but if I remove the UserDetailsService interface implementation from UserService class, then the application starts successfully. However, when ApplicationAuthenticationProvider is invoked by Spring, the UserService is not autowired into it and the application throws a NullPointerException.
java.lang.NullPointerException
at com.evidencefactory.security.ApplicationAuthenticationProvider.authenticate(ApplicationAuthenticationProvider.java:33)

Figured out how to put it to work, although there still some issues unanswered.
1) I still don't know why Spring context initialization fails when UserService implements UserDetailsService. Given that I'm not seeing use for it, since I'm using a custom AuthenticationProvider, I just removed this implementation and things are ok for now.
To the best of my knowledge (from what I could understand from my first initial reading of Spring Security reference documentation) providing a custom AuthenticationProvider or an UserDetailsService implementation are exclusive alternatives.
2) As noticed by one of the respondents (#Sotirios Delimanolis) I was instantiating ApplicatinoAuthenticationProvider by hand and since it wasn't being managed by Spring this instance would not have an UserService instance autowired into it. Based on this, I changed WebSecurityConfig to get an autowired instance of ApplicationAuthenticationProvider as can be seen below:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private ApplicationAuthenticationProvider authenticationProvider;
#Override
protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
authManagerBuilder.authenticationProvider(authenticationProvider);
}
}
This wasn't still sufficient, because ApplicationAuthenticationProvider wasn't being autowired into WebSecurityConfig. Based on this link Spring Security 3.1.3 #Autowired not Work when using WebApplicationInitializer I noticed that this was because security config should have a component scan declaration too. Adding #ComponentScan(basePackages = {"com.mypackage"}) to WebSecurityConfig resolved the problem.

I'm going to assume that UserService is a class and has some #Transactional annotation either on itself or one of its methods.
You'll need to add CGLIB to your classpath and change your #EnableTransactionManagement to
#EnableTransactionManagement(proxyTargetClass = true)
so that Spring uses CGLIB proxying (which can proxy classes) instead of JKD proxies (which cannot).
Alternatively, you can create an interface UserService and implement (and annotate with #Service) a UserServiceImpl class. Your autowired UserService field would remain the same, but Spring will be able to use JDK proxies.

Related

After implementing Spring Session Management Spring security keeps forwarding me to the login page

I am working on JEE application. We recently switched from container based security to spring security. I am now trying move session handling out of the container and into the application using spring-session-jdbc. I've created the required tables in our database and created the following SessionConfig file:
#Configuration
#EnableJdbcHttpSession
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
#Bean
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("java:jboss/MyDS");
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource) bean.getObject();
}
#Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
#Bean
public FindByIndexNameSessionRepository<?> sessionRepository(PlatformTransactionManager txManager,
DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
TransactionTemplate txTemplate = new TransactionTemplate(txManager);
return new JdbcIndexedSessionRepository(jdbcTemplate, txTemplate);
}
}
We have a security config where I autowire the the sessionRepository and use it to create the SessionAuthenticationStrategy like:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);
#Autowired
public FindByIndexNameSessionRepository<?> repo;
#Override
public void configure(WebSecurity web) throws Exception {
// put all static resource or external urls here
web.ignoring().antMatchers("/external/**", "/react/**", "/images/**", "/js/**", "/css/**",
"/vendor/**", "/fonts/**");
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
String maxSessions =
GenericPropertiesReader.getInstance().getValue("config.logins.max.sessions");
http.sessionManagement()// set the session management
.sessionAuthenticationStrategy(sessionAuthenticationStrategy())
.invalidSessionUrl("/login.html") // no user session forward here
.maximumSessions(Integer.valueOf(maxSessions))// 1 or -1 for unlimited
.maxSessionsPreventsLogin(false)// new session will terminate old session and forward them
// to the log in page
.expiredUrl("/login.html?type=expired-session");
http.headers().frameOptions().disable();
http.authorizeRequests()// put any antMatchers after this
.antMatchers("/login.html").permitAll() // permit any login page
.anyRequest().authenticated().and().formLogin() // we are using form login
.loginPage("/login.html") // show our custom login form
.loginProcessingUrl("/login") // post to Spring's action URL so our custom auth provider is invoked
.successHandler(successHandler()).failureHandler(failureHandler())
.permitAll() // so anyone can see it
.and().logout().logoutUrl("/logout")
.logoutSuccessHandler(new MyLogoutSuccessHandler())// our custom logout handler
.invalidateHttpSession(true) // delete session, need more work??
.deleteCookies("JSESSIONID") // and get rid of that cookie so they can't auto-login again
.permitAll()
.and().x509().x509AuthenticationFilter(this.x509AuthFilter());
}
#Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(x509AuthProvider()).authenticationProvider(loginAuthProvider());
}
#Bean
public PreAuthenticatedAuthenticationProvider x509AuthProvider() {
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(x509PreAuthUserDetailsService());
return provider;
}
#Bean // this irks me.
public AuthenticationManager myAuthenticationManager() throws Exception {
return this.authenticationManager();
}
#Bean
X509AuthenticationFilter x509AuthFilter() throws Exception {
X509AuthenticationFilter filter = new X509AuthenticationFilter();
filter.setAuthenticationSuccessHandler(x509SuccessHandler());
filter.setPrincipalExtractor(x509Extractor());
filter.setAuthenticationManager(this.myAuthenticationManager());
filter.setAuthenticationFailureHandler(failureHandler());
return filter;
}
#Bean
public X509PrincipalExtractor x509Extractor() {
return new MyX509DodIdExtractor();
}
#Bean
public MyX509PreAuthUserDetailsService x509PreAuthUserDetailsService() {
return new MyX509PreAuthUserDetailsService();
}
#Bean
public MyAuthenticationProvider loginAuthProvider() {
return new MyAuthenticationProvider ();
}
#Bean
MyAuthenticationSuccessHandler x509SuccessHandler() {
MyAuthenticationSuccessHandler handler = new MyAuthenticationSuccessHandler ();
handler.setForwardResonse(false);
return handler;
}
#Bean
public MyAuthenticationSuccessHandler successHandler() {
return new MyAuthenticationSuccessHandler();
}
#Bean
public MyAuthenticationFailureHandler failureHandler() {
MyAuthenticationFailureHandler failureHandler = new MyAuthenticationFailureHandler();
failureHandler.setExceptionMappings(LoginFailures.exceptionMap());
failureHandler.setDefaultFailureUrl("/login.html?login-failure=" + LoginFailures.DEFAULT.code);
return failureHandler;
}
#Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
#Bean
public SpringSessionBackedSessionRegistry<? extends Session> sessionRegistry()
throws IllegalArgumentException, NamingException {
return new SpringSessionBackedSessionRegistry<>(repo);
}
#Bean
public SessionAuthenticationStrategy sessionAuthenticationStrategy()
throws IllegalArgumentException, NamingException {
ConcurrentSessionControlAuthenticationStrategy sessionAuthenticationStrategy =
new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
return sessionAuthenticationStrategy;
}
}
I see the session tables in the database being filled when attempting to login. I never hit any of the authentication code when debugging. I just am redirected to the login page every time.
I feel like I must be missing something obvious. I was getting errors that there was no unique bean of type FindByIndexNameSessionRepository<?> until I changed the name of the bean in SessionConfig to sessionRepository. Which makes me think there's another bean of that type being instantiated by Spring (not in our code base) that might be interfering?

Can't inject dependencies in Spring Security configuration

I have a spring project using Spring Security. I want to inject dependencies into my WebSecurityConfigurerAdapter extending class but the dependencies do not seem to be getting injected. My controllers also use dependency injection and it does work there.
My SecSecurity class:
#Configuration
#Component
#EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserPrincipalDetailsService userPrincipalDetailsService;
LogoutSuccessHandler handler = new LogoutSuccess();
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
#Override
protected void configure(final HttpSecurity http) throws Exception {
http. logout().and().
httpBasic()
.and()
.authorizeRequests()
.antMatchers( "/", "/home", "/user", "/vestigingen", "/available", "/logout").permitAll()
.anyRequest().authenticated()
.and().logout().logoutSuccessHandler(handler).deleteCookies("JSESSIONID").invalidateHttpSession(false).permitAll()
.and().csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
#Bean
public UserDetailsService userDetailsService() {
return new UserPrincipalDetailsService();
}
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(this.userPrincipalDetailsService);
return daoAuthenticationProvider;
}
}
It cannot find beans for the userPrincipalDetailsService class.
UserPrincipalDetailService class:
#Component
public class UserPrincipalDetailsService implements UserDetailsService {
private UserRepositorySQL userRepository = new UserRepositorySQL();
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
UserEntity user = userRepository.findUserByUsername(s);
UserPrincipal userPrincipal = new UserPrincipal(user);
return userPrincipal;
}
}
to clarify: I can't inject any dependencies within my SecSecurityConfig class eventhough i have tried annotating it in many different ways.
Define the bean name #Component("userPrincipalDetailsService") in the UserPrincipalDetailsService class.
#Component("userPrincipalDetailsService")
public class UserPrincipalDetailsService implements UserDetailsService {
private UserRepositorySQL userRepository = new UserRepositorySQL();
#Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
UserEntity user = userRepository.findUserByUsername(s);
UserPrincipal userPrincipal = new UserPrincipal(user);
return userPrincipal;
}
}

PrincipalExtractor and AuthoritiesExtractor doesn't hit

I have a project with Spring security and Oauth2.
On the resource server I have the following configuration:
#Configuration
public class SecurityConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(final HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests().antMatchers("/info", "/health", "/h2-console/**").permitAll()
.anyRequest().authenticated()
.and().headers().frameOptions().disable();
}
}
I have the following extractors:
#Component
public class InsurancePrincipalExtractor implements PrincipalExtractor {
#Override
public Object extractPrincipal(Map<String, Object> map) {
return map.get("username");
}
}
#Component
public class InsuranceAuthoritiesExtractor implements AuthoritiesExtractor {
#Override
public List<GrantedAuthority> extractAuthorities(Map<String, Object> map) {
//Logic
}
I set the user-info-uri: http://localhost:8081/uaa/v1/me
The problem is that it does not hit my extractor methods at runtime, so nothing happens. As I know I just need to annotate it with the #Component and the Spring boot and will use it auto.
UPDATE:
Solution founded.
I had to add this to my configuration as well:
#Bean
protected ResourceServerTokenServices resourceServerTokenServices(ResourceServerProperties sso,
OAuth2ClientContext oauth2ClientContext,
UserInfoRestTemplateFactory restTemplateFactory) {
UserInfoTokenServices services = new UserInfoTokenServices(sso.getUserInfoUri(), sso.getClientId());
services.setRestTemplate(restTemplateFactory.getUserInfoRestTemplate());
services.setTokenType(sso.getTokenType());
return services;
}

Spring security annotations don't work on service layer

I'm using Spring security to define access rules at method-level and facing with the issue is Spring security annotations are not working on service layer. But they work normal on controller layer.
Here are my configuration:
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/lostpassword")
.antMatchers("/api/resetpassword");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
private static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {
#Autowired
private MutableAclService mutableAclService;
#Autowired
private RoleHierarchy roleHierarchy;
public GlobalSecurityConfiguration() {
super();
}
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(mutableAclService));
expressionHandler.setRoleHierarchy(roleHierarchy);
return expressionHandler;
}
}
}
Service does not work:
#Override
#PreAuthorize("hasRole('ROLE_ADMIN')")
public Iterable<Appliance> getAll() {
return applianceRepo.findAll();
}
Controller works well:
#PreAuthorize("hasRole('ROLE_ADMIN')")
#RequestMapping(method = RequestMethod.GET)
public ResponseEntity<PagedResources<Appliance>> getPage(#PageableDefault Pageable pageable, PagedResourcesAssembler pagedAssembler) {
Page<Appliance> appliancePage = applianceService.getPage(pageable);
return ResponseEntity.ok(pagedAssembler.toResource(appliancePage, applianceAssembler));
}
I realized that I'm wrong when putting #PreAuthorize on getAll() method but I was testing on getPage(pageable) method. Spring security configurations work well. Sorry for any inconveniences.

Spring security in spring boot application

I am trying to implement security to my spring boot application and have followed this http://justinrodenbostel.com/2014/05/30/part-5-integrating-spring-security-with-spring-boot-web/ . after implementing this i am getting an error as following :
Expression parsing failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire method: public void
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.setContent
NegotationStrategy(org.springframework.web.accept.ContentNegotiationStrategy);
This is my Application.class
public class Application extends WebMvcConfigurerAdapter{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Value("${spring.datasource.driverClassName}")
private String databaseDriverClassName;
#Value("${spring.datasource.url}")
private String datasourceUrl;
#Value("${spring.datasource.username}")
private String databaseUsername;
#Value("${spring.datasource.password}")
private String databasePassword;
#Bean
public DataSource datasource() {
org.apache.tomcat.jdbc.pool.DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource();
ds.setDriverClassName(databaseDriverClassName);
ds.setUrl(datasourceUrl);
ds.setUsername(databaseUsername);
ds.setPassword(databasePassword);
return ds;
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
#Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.US);
return slr;
}
public LocaleChangeInterceptor localeChangeInterceptor()
{
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang");
return lci;
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
// TODO Auto-generated method stub
registry.addInterceptor(localeChangeInterceptor());
}
I have two model classes named Gizmo.java and GizmoChild.java
This is my Controller class
#Controller
public class SampleController {
#RequestMapping("/")
public String index(Model model) {
Gizmo gizmo = new Gizmo();
gizmo.getChildren().add(new GizmoChild());
model.addAttribute("gizmo", gizmo);
return "hello";
}
#RequestMapping("/save")
public String save(Gizmo gizmo) {
System.out.println(gizmo.getField1());
System.out.println(gizmo.getField2());
for(GizmoChild child : gizmo.getChildren()) {
System.out.println(child.getChildField1());
System.out.println(child.getChildField2());
}
return "redirect:/";
}
}
This is my SecurityConfiguration.java
#Configuration
#EnableWebMvcSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource datasource;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated();
http
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.loginPage("/login")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login")
.permitAll();
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
JdbcUserDetailsManager userDetailsService = new JdbcUserDetailsManager();
userDetailsService.setDataSource(datasource);
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
auth.jdbcAuthentication().dataSource(datasource);
auth.userDetailsService(userDetailsService);
if(!userDetailsService.userExists("user")) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
User userDetails = new User("user", encoder.encode("password"), authorities);
userDetailsService.createUser(userDetails);
}
}
}
I am not getting any compilation errors but while running error is coming.
Please help me to resolve this issue .This is the only place i am stuck , if there are any documentation regarding spring boot security please tell me.

Resources