0

I recently started to work on a project using Spring. First time I'm using Spring. In this project I was asked to implement both Java and XML Spring security. I started searching to see how can I achieve this, with little to none success.

How to implement Spring Security 4 with both XML and Java config

In this post, this guy manage to achieve it but I tried to do the same and I just get: Error creating bean with name 'org.springframework.security.access.SecurityConfig': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.security.access.SecurityConfig]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.security.access.SecurityConfig.()

Looked for the error and I'll I got was solutions based on Spring-Boot which I'm not using.

Maybe I'm doing something awfully wrong but this, as I said, is the first time I'm using spring so I'm kind of lost.

Here's my AppConfig class:

@Configuration
@ComponentScan(basePackages = { "com.configuration" })
@PropertySource("classpath:application.properties")
public class AppConfig {

    @Autowired
    private Environment env;

    @Bean
    public JavaMailSenderImpl javaMailSenderImpl() {
        final JavaMailSenderImpl mailSenderImpl = new JavaMailSenderImpl();
        mailSenderImpl.setHost(env.getProperty("smtp.host"));
        mailSenderImpl.setPort(env.getProperty("smtp.port", Integer.class));
        mailSenderImpl.setUsername(env.getProperty("smtp.username"));
        mailSenderImpl.setPassword(env.getProperty("smtp.password"));
        final Properties javaMailProps = new Properties();
        javaMailProps.put("mail.smtp.starttls.enable", Boolean.valueOf(env.getProperty("server.tls")));
        javaMailProps.put("mail.smtp.auth", true);
        mailSenderImpl.setJavaMailProperties(javaMailProps);
        return mailSenderImpl;
    }

    @Bean
    public CommonsMultipartResolver multipartResolver(){
        CommonsMultipartResolver resolver=new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        return resolver;
    }
}

Java SpringSecutiry class:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("customUserDetailsService")
    private UserDetailsService userDetailsService;

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService);
        authenticationManagerBuilder.authenticationProvider(customAuthenticationProvider());
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider customAuthenticationProvider() {
        DaoAuthenticationProvider customAuthenticationProvider = new CustomDaoAuthenticationProvider();
        customAuthenticationProvider.setUserDetailsService(userDetailsService);
        customAuthenticationProvider.setPasswordEncoder(passwordEncoder());
        return customAuthenticationProvider;
    }

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

    @Bean
    public CustomAuthenticationEntryPoint customAuthenticationEntryPoint(){
        return new CustomAuthenticationEntryPoint();
    }

    @Bean
    public CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler(){
        return new CustomAuthenticationSuccessHandler();
    }

    @Bean
    public CustomAuthenticationFailureHandler customAuthenticationFailureHandler(){
        CustomAuthenticationFailureHandler customAuthenticationFailureHandler = new CustomAuthenticationFailureHandler();
        customAuthenticationFailureHandler.setDefaultFailureUrl("/signin.html");
        return customAuthenticationFailureHandler;
    }

    @Bean
    public CustomLogoutSuccessHandler customLogoutSuccessHandler(){
        return new CustomLogoutSuccessHandler();
    }

    @Bean
    public CustomAccessDeniedHandler customAccessDeniedHandler(){
        return new CustomAccessDeniedHandler();
    }

    @Bean
    public CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter() {
        try {
            CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter = new CustomUsernamePasswordAuthenticationFilter();
            customUsernamePasswordAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
            customUsernamePasswordAuthenticationFilter.setAuthenticationSuccessHandler(customAuthenticationSuccessHandler());
            customUsernamePasswordAuthenticationFilter.setAuthenticationFailureHandler(customAuthenticationFailureHandler());
            customUsernamePasswordAuthenticationFilter.setFilterProcessesUrl("/login");
            customUsernamePasswordAuthenticationFilter.setUsernameParameter(IConstants.USERNAME_FIELD);
            customUsernamePasswordAuthenticationFilter.setPasswordParameter(IConstants.PASSWORD_FIELD);
            return customUsernamePasswordAuthenticationFilter;
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/signin**").permitAll()
        //.antMatchers("/dashboard**").hasRole("ROLE_USER")
        .and().addFilterBefore(customUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
        .logout().permitAll().logoutSuccessUrl("/signin.html").deleteCookies("JSESSIONID").invalidateHttpSession(true).logoutSuccessHandler(customLogoutSuccessHandler())
        .and().exceptionHandling().authenticationEntryPoint(customAuthenticationEntryPoint())
        .accessDeniedHandler(customAccessDeniedHandler())
        .and().formLogin().loginPage("/login")
        .and().csrf().disable();
    }
}

And the Spring security XML:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.0.xsd">

    <http auto-config="true" >
        <intercept-url pattern="/dashboard**" access="hasRole('ROLE_USER')" />
    </http>
</beans:beans>

I tried adding on the Web.xml file the spring-security.xml declaration, but all it did was say that theres a double declaration of the springSecurity filter, also tried using the @Import annotation and the result I got was that the Java file was completely ignored, the XML was the one with the configuration.

The intention here is, I commented the ".antMatchers("/dashboard**").hasRole("ROLE_USER")" line on the Java file and added it to the XML so that i can add any matcher there and be implemented on the security.

Thank you for any help you can provide.

Community
  • 1
  • 1
  • `In this project I was asked to implement both Java and XML Spring security.` I'm curious about this requirement. Does it mean you have to duplicate your security configuration in some way? I see little sense in that. Once you get the java security set up, why not go with that for the whole stuff? You'll avoid problems. – Aritz Jun 20 '16 at 14:57
  • The reason is that, if the want to change the access to certain path to another roles, lets say /dashboard** now is not for users but for admins, to avoid a build, which with java you would have to do. Though I'm not sure if with XML you dont. I still find it kind of awkward because either way you'll have to re-deploy the app. And doing a build is not a big deal. – IKnowNothing Jun 20 '16 at 15:46
  • As far as I'm concerned, Spring parses the configuration files when the context starts. Then, it simply makes no difference to have it configured in xml or java. – Aritz Jun 20 '16 at 15:49
  • OK, let me look for some information about that. If I can find it maybe they'll stay with just Java config. Thanks for the help :) – IKnowNothing Jun 20 '16 at 15:52

0 Answers0