spring - 如何使用 Java 配置为登录页面配置 Spring MVC HttpSecurity

标签 spring spring-mvc spring-security

我正在使用 Java 配置而不是 xml 构建 Spring MVC 应用程序,使用 Eclipse、Maven 和 Spring webmvc 版本 4.2.4 以及 Spring security 4.0.3。我让它在 Tomcat 7 上运行。 我可以从一个导航到另一个jsp,因此@RequestMappings 是正确的(它们在下面的configure( ) 方法中列出)。我已经使用 log4j 设置了日志记录,并记录了所有可能的内容,因此我可以看到我的配置和 Controller 正在被调用。在启动过程中,日志文件显示正在设置的映射:

...RequestMappingHandlerMapping - Mapped "{[/login],methods=[GET]}"... ...RequestMappingHandlerMapping - Mapped "{[/login],methods=[POST]}" ...

我的问题是登录屏幕在提交时不会 POST 到 LoginController 类中的正确方法,它会继续转到为 GET 请求注释的“init”方法。

这是SecurityConfig:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

   @Autowired
   public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
    .withUser("user").password("password").roles("USER");
   }

   @Override
   protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/","/register","/about","/home","/demo").permitAll()
    //.loginProcessingUrl("/login")
    .antMatchers(HttpMethod.POST,"/login").permitAll()
    .anyRequest().authenticated()
    .and().formLogin().permitAll().loginPage("/login")
    .and().logout().logoutUrl("/logout").invalidateHttpSession(true).logoutSuccessUrl("/home");
   }
}

当//.loginProcessingUrl("/login") 取消注释时,会出现自动生成的 Spring 登录表单,我可以登录!所以它适用于默认表单,但不适用于我的表单。

LoginController.java 如下所示:

@Controller
public class LoginController {
   private Logger logger = Logger.getLogger(LoginController.class);

   @RequestMapping(value = "/login", method = RequestMethod.GET)
   public String init(Locale locale, Model model) {
    logger.info("LoginController login INIT!");
    return "login";
   }

   @RequestMapping(value = "/login", method = RequestMethod.POST)
   public String login(@ModelAttribute LoginDTO loginObject, Locale locale, Model model) {
    logger.info("LoginController login POST!");
    return "home";
   }

}

提交 Spring 默认登录页面时,它不会映射到我的 LoginController。当提交我的login.jsp 时,请求进入init( ) 方法,而不是映射到POST 的login( ) 方法。

我想要使用的自定义login.jsp片段,而不是默认的jsp:

 <form:form action="${loginProcessingUrl}" method="post">
        <p>
        <label for="username">Username</label>
        <input type="text" id="userId" name="userId"/>
        </p>
        <p>
        <label for="password">Password</label>
        <input type="password" id="password" name="password"/>
        </p>
        <div>
            <button type="submit">Log in</button>
        </div>
 </form:form>

该框架正在登录页面上添加 CSRF token ,我可以在浏览器上看到该 token ,因此这似乎有效,但我不确定它是否重要。

<input type="hidden" name="_csrf" value="ac81daad-f2e4-4357-a7a8-b7b10a67036f">

我刚刚学习 Spring,一直在到处寻找一些关于 Spring Security 如何工作和配置的深入解释,特别是带有所有链接方法的 http 对象。如果有人可以指导我找到最新 Spring Security 的良好引用,我将不胜感激,或者让我知道我的代码中需要什么。

最佳答案

根据我的理解,您应该从 Controller 中删除 @RequestMapping(value = "/login", method = RequestMethod.POST) 并更改安全配置,如下所示:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
      .withUser("user").password("password").roles("USER");
  }

  @Override
  protected void configure(HttpSecurity http) throws Exception {  
    http.authorizeRequests()
      .antMatchers("/", "/register", "/about", "/home", "/demo").permitAll()
      .anyRequest().authenticated()
      .and()
    .formLogin()
      .loginPage("/login")
      .loginProcessingUrl("/login")
      .permitAll()
      .and()
    .logout()
      .logoutUrl("/logout")
      .logoutSuccessUrl("/home")
      .invalidateHttpSession(true);
   }
}

Spring 将使用 Spring 安全过滤器自动处理您的 POST 请求,并在必要时将您重定向到登录表单。请确保您的登录字段名称正确命名为“用户名”和“密码”:

<form:form action="${loginProcessingUrl}" method="post">
    <p>
    <label for="username">Username</label>
    <input type="text" id="username" name="username"/>
    </p>
    <p>
    <label for="password">Password</label>
    <input type="password" id="password" name="password"/>
    </p>
    <div>
        <button type="submit">Log in</button>
    </div>
</form:form>

参见http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#jc-form了解更多信息。

关于spring - 如何使用 Java 配置为登录页面配置 Spring MVC HttpSecurity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34733975/

相关文章:

java - @ReplaceWithMock 不使用 Springmockito 注释进行模拟

java - 创建 bean 时出错 - 在服务中注入(inject)配置类不起作用

java - wicket @SpringBean 无法创建 bean

json - Spring MVC : jackson-mapper-asl not work with Spring 4

javascript - Spring MVC JavaScript

spring - 在每个请求中设置 cookie - SPRING

Grails OpenId 插件错误

java - 我可以将复杂对象作为输入传递给 Spring WebFlow 子流吗?

spring - 在使用 Spring 进行集成测试期间模拟外部服务器

java - Spring Boot登录错误