不支持Spring Security Request方法'POST'

时间:2014-10-10 14:55:11

标签: spring spring-mvc spring-security spring-java-config

状态为405且身份验证的页面无效。

Spring Boot日志错误

  

o.s.web.servlet.PageNotFound:不支持请求方法'POST'

来自jsp页面的错误:

  

Whitelabel错误页面

     

此应用程序没有/ error的显式映射,因此您将此视为后备。

     

出现意外错误(type = Method Not Allowed,status = 405)。   请求方法'POST'不受支持

春天信息:
- 使用Spring Security 3.2.5
- 使用Spring Boot App启动服务器。
- Spring-Java-Config

代码:

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;
    }
}

2 个答案:

答案 0 :(得分:1)

尝试将 login-processing-url 添加到SecurityConfig

XML中的

看起来像这样

   <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" />

答案 1 :(得分:0)

似乎您启用了CSRF。你能检查一下你是否在表单中传递了CSRF令牌。如果没有,请在表单中添加以下行。

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