我正在使用Java配置而不是xml构建Spring MVC应用程序,使用Eclipse,Maven和Spring webmvc ver 4.2.4以及Spring security 4.0.3。我在Tomcat 7上运行它。 我可以从一个jsp导航到另一个jsp,因此@RequestMappings是正确的(它们在下面的configure()方法中列出)。我已经使用log4j设置日志记录,并且可以记录所有内容,因此我可以看到正在调用我的配置和控制器。在启动期间,日志文件显示正在设置的映射:
... RequestMappingHandlerMapping - Mapped" {[/ login],methods = [GET]}" ... ... RequestMappingHandlerMapping - 映射" {[/ login],methods = [POST]}" ...
我的问题是登录界面在提交时没有POST到LoginController类中的正确方法,它会继续进入" init"为GET请求注释的方法。
这是 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令牌,我可以在浏览器上看到,所以这似乎有效,但我不确定它是否重要。
<input type="hidden" name="_csrf" value="ac81daad-f2e4-4357-a7a8-b7b10a67036f">
我正在学习Spring,并且一直在寻找有关Spring Security如何工作和配置的深入解释,尤其是具有所有链接方法的http对象。如果有人能指导我对最新的Spring Security有一个很好的参考,我会很感激,或者让我知道我的代码需要什么。
答案 0 :(得分:3)
根据我的理解,您应该从控制器中删除@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请求,并在必要时将您重定向到您的登录表单。请确保您的登录字段名称已正确命名&#34;用户名&#34;和&#34;密码&#34;:
<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。