Eliz Liew
Eliz Liew

Reputation: 31

Spring Security Request method 'POST' not supported

The page having status 405 and also authentication is not working.

Error from Spring Boot log

o.s.web.servlet.PageNotFound : Request method 'POST' not supported

Error from jsp page:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

There was an unexpected error (type=Method Not Allowed, status=405). Request method 'POST' not supported

Spring Info:
- Using Spring Security 3.2.5
- Using Spring Boot App to start up server.
- Spring-Java-Config

Codes:

SecurityConfig.java

@EnableAutoConfiguration
@ComponentScan(basePackages = { "org.myakasha.crm","org.myakasha.crm.controller","org.myakasha.crm.model"})
@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired
DataSource dataSource;

@Autowired
public void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
    
    auth.jdbcAuthentication().dataSource(dataSource)
        .usersByUsernameQuery("select username,password, enabled from users where username=?")
        .authoritiesByUsernameQuery("select username, role from user_roles where username=?");
}

 @Override
 public void configure(WebSecurity web) throws Exception {
     web.ignoring().antMatchers("/resources/**");
 }


@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests()
        .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
        .and()
            .formLogin().loginPage("/login").failureUrl("/login?error").usernameParameter("username").passwordParameter("password")
        .and()
            .logout().logoutSuccessUrl("/login?logout")
        .and()
            .exceptionHandling().accessDeniedPage("/403")
        .and()
            .csrf();
    
    }
}

SecurityController.java

@Controller
public class SecurityController {

@RequestMapping(value = { "/welcome**" }, method = RequestMethod.GET)
public ModelAndView defaultPage() {

    ModelAndView model = new ModelAndView();
    model.addObject("title", "Spring Security + Hibernate Example");
    model.addObject("message", "This is default page!");
    model.setViewName("hello");
    return model;

}

@RequestMapping(value = "/admin**", method = RequestMethod.GET)
public ModelAndView adminPage() {

    ModelAndView model = new ModelAndView();
    model.addObject("title", "Spring Security + Hibernate Example");
    model.addObject("message", "This page is for ROLE_ADMIN only!");
    model.setViewName("admin");

    return model;

}

@RequestMapping(value = "/login", method = {RequestMethod.GET} )
public ModelAndView login(@RequestParam(value = "error", required = false) String error,
        @RequestParam(value = "logout", required = false) String logout, HttpServletRequest request) {

    ModelAndView model = new ModelAndView();
    if (error != null) {
        model.addObject("error", getErrorMessage(request, "SPRING_SECURITY_LAST_EXCEPTION"));
    }

    if (logout != null) {
        model.addObject("msg", "You've been logged out successfully.");
    }
    model.setViewName("login");

    return model;

}

// customize the error message
private String getErrorMessage(HttpServletRequest request, String key) {

    Exception exception = (Exception) request.getSession().getAttribute(key);

    String error = "";
    if (exception instanceof BadCredentialsException) {
        error = "Invalid username and password!";
    } else if (exception instanceof LockedException) {
        error = exception.getMessage();
    } else {
        error = "Invalid username and password!";
    }

    return error;
}

// for 403 access denied page
@RequestMapping(value = "/403", method = RequestMethod.GET)
public ModelAndView accesssDenied() {

    ModelAndView model = new ModelAndView();

    // check if user is login
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (!(auth instanceof AnonymousAuthenticationToken)) {
        UserDetails userDetail = (UserDetails) auth.getPrincipal();
        System.out.println(userDetail);

        model.addObject("username", userDetail.getUsername());

    }

    model.setViewName("403");
    return model;

    }
}

WebConfig.java

@EnableAutoConfiguration
@EnableWebMvc
@ComponentScan(basePackages = {"org.myakasha.crm","org.myakasha.crm.controller","org.myakasha.crm.model"})
public class WebConfig extends WebMvcConfigurerAdapter{

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}


/**
 * This function to replace servlet-content.xml
 * Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory 
 **/
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
    viewResolver .setPrefix("/WEB-INF/views/");
    viewResolver .setSuffix(".jsp");
    return viewResolver ;
}

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasenames("classpath:message");
    messageSource.setUseCodeAsDefaultMessage(true);
    messageSource.setDefaultEncoding("UTF-8");
    return messageSource;
    }
}

PersistenceConfig.java

@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "org.myakasha.crm" })
public class PersistenceConfig {

@Autowired
private Environment env;

public PersistenceConfig() {
    super();
}

@Bean
public LocalSessionFactoryBean sessionFactory() {
    final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(restDataSource());
    sessionFactory.setPackagesToScan(new String[] { "org.myakasha.crm.model" });
    sessionFactory.setHibernateProperties(hibernateProperties());

    return sessionFactory;
}

@Bean
public DataSource restDataSource() {
    final BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
    dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
    dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
    dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));

    return dataSource;
}

@Bean
@Autowired
public HibernateTransactionManager transactionManager(final SessionFactory sessionFactory) {
    final HibernateTransactionManager txManager = new HibernateTransactionManager();
    txManager.setSessionFactory(sessionFactory);

    return txManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}

final Properties hibernateProperties() {
    final Properties hibernateProperties = new Properties();
    hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
    hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));

    hibernateProperties.setProperty("hibernate.show_sql", "true");
    // hibernateProperties.setProperty("hibernate.format_sql", "true");
    // hibernateProperties.setProperty("hibernate.globally_quoted_identifiers", "true");

    return hibernateProperties;
    }
}

Upvotes: 3

Views: 10206

Answers (2)

Chathuranga Tennakoon
Chathuranga Tennakoon

Reputation: 2189

it seems to be that you have enabled the CSRF. can you check whether you are passing the CSRF token, in the form. if not please add the following line to your form.

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

Upvotes: 0

MAFH
MAFH

Reputation: 11

try to add login-processing-url to the SecurityConfig

in XML it looks like this

   <form-login 
                    login-page="/login"

<!-- for <form method="post" action="/login-process"> -->
                    login-processing-url="/login_process"

                    default-target-url="/home"
                    authentication-failure-url="/login?error"
                    username-parameter="username"
                    password-parameter="password" />

Upvotes: 1

Related Questions