我使用的是Spring-Boot 1.1.7,带有春季安全性,html(没有百里香叶)和javascript。使用javascript提交登录名时,我无法使登录名正常工作。当我将html与表单一起使用时,spring-security会接受请求,进行身份验证并愉快地进行。但是使用Javascript,我得到了302重定向并且没有身份验证。
这是我的配置:
@ComponentScan
@EnableAutoConfiguration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class MyApplication {
public static void main(String[] args) {
ApplicationContext edm = SpringApplication.run( MyApplication.class, args );
}
}
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/menu").permitAll()
.antMatchers("/error").permitAll()
.antMatchers("/resources/**").permitAll()
.antMatchers("/css/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/fonts/**").permitAll()
.antMatchers("/libs/**").permitAll();
http
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/")
.permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
.permitAll();
http
.sessionManagement()
.maximumSessions(1)
.expiredUrl("/login?expired")
.maxSessionsPreventsLogin(true)
.and()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/");
http
.authorizeRequests().anyRequest().authenticated();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
PasswordEncoder encoder = new BCryptPasswordEncoder();
auth.userDetailsService( customUserDetailsService ).passwordEncoder( encoder );
}
@Override
public void configure(WebSecurity security){
security.ignoring().antMatchers("/css/**","/fonts/**","/libs/**");
}
}
我有自己的UserDetailsService
@Component
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userService.findByUsername( userName );
if ( user == null ) {
throw new UsernameNotFoundException( "UserName " + userName + " not found" );
}
return user;
}
}
最后,这是提交帖子的javascript:
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$("#login").click(function(){
username=$("#username").val();
password=$("#password").val();
$.ajax({
type: "POST",
url: "/login",
beforeSend: function(xhr){
xhr.setRequestHeader(header, token);
},
data: "username="+username+"&password="+password,
success: function(html){
alert("logged in");
}
});
return false;
});
如果我从url / login进行此调用,则会得到spring提供的登录表单,并且一切正常。但是我需要使用javascript,所以我想知道是否需要做些其他的事情来告诉spring寻找它?
这是为我工作的答案/解决方案。根据本文(http://patrickgrimard.com/2014/01/03/spring-security-csrf-protection-in-a-backbone-single-page-app/),添加了aCSRFTokenGeneratorFilter extends OncePerRequestFilter
并将其连接到我的安全性上配置,允许使用我的javascript提供的参数。
public final class CSRFTokenGeneratorFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
CsrfToken token = (CsrfToken) request.getAttribute("_csrf");
response.setHeader("X-CSRF-HEADER", token.getHeaderName());
response.setHeader("X-CSRF-PARAM", token.getParameterName());
response.setHeader("X-CSRF-TOKEN", token.getToken());
filterChain.doFilter(request, response);
}
}
接线为:
@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterAfter(new CSRFTokenGeneratorFilter(), CsrfFilter.class)
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
..}
}
我不确定为什么需要过滤器,但是我想spring-boot / security不会使用它作为默认值。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句