spring boot / spring安全性是从javascript忽略/登录调用 [英] spring boot / spring security is ignoring /login call from javascript

查看:109
本文介绍了spring boot / spring安全性是从javascript忽略/登录调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Spring-Boot 1.1.7,带有spring security,html(没有百里香叶)和javascript。当我使用javascript提交登录信息时,我无法使登录正常工作。当我使用带有表单的html时,spring-security接收请求,进行身份验证并愉快地继续进行。但是使用Javascript,我得到302重定向而没有身份验证。

I am using Spring-Boot 1.1.7, with spring security, html (no thyme-leaf) and javascript. I am unable to get my login to work correctly when I use javascript to submit my login. When I use html with a form, spring-security picks up the requests, authenticates and proceeds happily. But with Javascript, I get a 302 redirect and no authentication.

这是我的配置:

@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/**");
    }
}

我有自己的UserDetailsS​​ervice

And I have my own 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 :

And finally, here is the javascript that submits the post:

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

如果我从网址/登录进行此调用,我会获得弹簧提供的登录表单并且所有工作完美。但我需要使用javascript,所以我想知道是否有什么不同我需要做的告诉Spring寻找它?

If I make this call from the url /login, I get the spring provided login form and all works perfectly. but I have a need to use javascript so I am wondering if there is something different I need to do to tell spring to look for it?

推荐答案

以下是适合我的答案/解决方案。基于这篇文章( http://patrickgrimard.com/2014/01/03/spring-security-csrf-protection-in-a-backbone-single-page-app/ ),添加 CSRFTokenGeneratorFilter扩展OncePerRequestFilter 并将其连接到我的安全配置,允许使用我提供的javascript参数。

Here is the answer/solution that worked for me. Based on this article (http://patrickgrimard.com/2014/01/03/spring-security-csrf-protection-in-a-backbone-single-page-app/), adding a CSRFTokenGeneratorFilter extends OncePerRequestFilter and wiring it up to my security config, allowed my javascript provided parameters to be used.

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不会将其用作默认。

I am not sure why the filter is needed, but I guess spring-boot/security doesn't use that as a default.

这篇关于spring boot / spring安全性是从javascript忽略/登录调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆