Java 使用Spring安全性和CSRF保护登录/注销Spring应用程序
我正在基于SpringSecurityHelloWorld示例构建一个SpringWeb应用程序。我试图通过SpringSecurity实现登录和注销。我可以成功登录,但无法注销。重定向按预期进行,但在注销后登录页面尝试加载时:Java 使用Spring安全性和CSRF保护登录/注销Spring应用程序,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,我正在基于SpringSecurityHelloWorld示例构建一个SpringWeb应用程序。我试图通过SpringSecurity实现登录和注销。我可以成功登录,但无法注销。重定向按预期进行,但在注销后登录页面尝试加载时: <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> 以下是jsp中的注销表单: <c:url var=
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
以下是jsp中的注销表单:
<c:url var="logoutUrl" value="/logout"/>
<form action="${logoutUrl}" method="post">
<input type="submit" value="Logout" />
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
我的登录控制器(我认为它实际上没有被实现,在这里设置多个从未被命中的断点):
和我的安全配置类:
@Configuration
@EnableWebSecurity
public class RobotSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
RobotLoginSuccessHandler robotLoginSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN","USER");
}
最后编写了一个实现LogoutSuccessHandler的类。我完全从stock LogoutSuccessHandler复制了这些方法。然后,我修改了SecurityConfiguration类以包含注销参数:
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.and().logout().logoutUrl("/login?logout").addLogoutHandler(robotLogoutSuccessHandler)
.permitAll();
}
我想,由于我定义了自己的配置类,我需要指定我希望LogoutHandler执行的确切位置。您能显示spring安全配置文件吗?更新了问题并添加了其他文件。默认配置要求您的角色以“角色”开头除非您更改org.springframework.security.vote.RoleVoter的rolePrefix。尝试添加ROLE_uuxi。我认为在使用annotations方法时,这不适用。根据:“在#1和#2中创建用户时,我们不会像在XML配置中那样指定“角色”。由于这种约定非常常见,“角色”方法会自动为您添加“角色”。如果您不想添加“角色”,可以改为使用权限方法。”
@EnableWebMvc
@ComponentScan("com.robot.configuration")
public class LoginController extends WebMvcConfigurerAdapter {
protected final Log logger = LogFactory.getLog(getClass());
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
}
@Configuration
@EnableWebSecurity
public class RobotSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
RobotLoginSuccessHandler robotLoginSuccessHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().csrf()
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser("admin").password("password").roles("ADMIN","USER");
}
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.antMatchers("/", "/home").access("hasRole('USER')")
.antMatchers("/admin/**").access("hasRole('ADMIN')")
.and().formLogin().loginPage("/login").successHandler(robotLoginSuccessHandler)
.usernameParameter("username").passwordParameter("password")
.and().exceptionHandling().accessDeniedPage("/Access_Denied")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.and().logout().logoutUrl("/login?logout").addLogoutHandler(robotLogoutSuccessHandler)
.permitAll();
}