spring-security Sping Boot +安全性+ jquery AJAX

mum43rcc  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(160)

嗨,我用spring Boot 和spring security构建了一个项目。现在,我想为Jquery. AJAX ({...})提供登录restfull服务;我想:

1.处理来自HTML页面的登录请求(如<form>提交)。
1.“自动”用于在HTML页面请求时检查会话超时,将超时重定向到登录页面。
1.处理来自 AJAX 的登录请求。

  1. automatic用于在 AJAX 请求时检查登录状态。
    “我的代码是这样的”

安全配置

从Web安全配置器适配器扩展

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable();

    http.exceptionHandling().authenticationEntryPoint((request, response, authException) -> {
        String requestType = request.getHeader("x-requested-with");
        if (!StringUtils.isEmpty(requestType)) {
            response.setStatus(HttpServletResponse.SC_OK);
            response.getWriter().print("{\"invalid_session\": true}");
            response.getWriter().flush();
        } else {
            response.sendRedirect("/security/login");
        }
    });

    http.authorizeRequests()
            .antMatchers("/security/**").permitAll()
            .antMatchers("/reader/**").hasRole("READER")
            .anyRequest().authenticated()

            // session time out
            .and().sessionManagement().invalidSessionUrl("/security/session_timeout")

            .and().cors()

            // login
            .and()
            .formLogin()
            .successHandler(successHandler)
            .failureHandler(faildHandler)
            .loginPage("/security/login")
            .permitAll()

            // logout
            .and()
            .logout().permitAll();
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(readerRepository::findOne);
}

我有两个处理程序来处理验证成功和验证失败

失败处理程序

从简单URL验证失败处理程序扩展

@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
    System.out.println("Failed to auth.");
    String requestType = request.getHeader("x-requested-with");
    if (!StringUtils.isEmpty(requestType)) {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.getWriter().print("{\"success\": false}");
    } else {
        setDefaultFailureUrl("/security/login?error=true");
        super.onAuthenticationFailure(request, response, exception);
    }
}

成功处理程序

从保存的请求感知验证成功处理程序扩展

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    System.out.println("Success to auth.");
    String requestType = request.getHeader("x-requested-with");
    if (!StringUtils.isEmpty(requestType)) {
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().print("{\"success\": true}");
    } else {
        setDefaultTargetUrl("/index/index");
        setAlwaysUseDefaultTargetUrl(true);
        super.onAuthenticationSuccess(request, response, authentication);
    }
}

控制器

基本请求Map为'/security'

@RequestMapping(value = "/login")
public String login(@RequestParam(value = "error", defaultValue = "false") boolean error, Model model) {
    model.addAttribute("error", error);
    return "login";
}

@RequestMapping("/session_timeout")
public void sessionTimeout(HttpServletRequest request, HttpServletResponse response) throws IOException {
    System.out.println("session was timeout.");
    if (request.getHeader("x-requested-with") != null) {
        // handler for ajax
        response.getWriter().print("{\"sessionTimeout\": true}");
        response.getWriter().close();
    } else {
        response.sendRedirect("login");
    }
}

***当我在页面(thymeleaf)中测试时,所有的都工作了。******但是..当我使用Jquery AJAX 时。***问题:

当我使用Jquery. AJAX ({})API发送请求时,请求无法到达服务器。如何使用jquery编写ajax请求,我尝试了很多Jquery方法,页面在控制台中没有响应代码。

kninwzqo

kninwzqo1#

谢谢你,范哥,我把它修好了。我重新写了登录认证:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(userDetails, userReq.getPassword(), userDetails.getAuthorities());
authenticationManager.authenticate(token);
if (token.isAuthenticated()) {
    SecurityContextHolder.getContext().setAuthentication(token);
    return true;
}

使用AuthenticationManager进行身份验证,它从Spring注入。
如果认证成功,我会将sessionid返回给客户端,客户端保存在cookie中,当客户端发出请求时,客户端总是在 AJAX 请求的url的末尾统计sessionid。如果认证失败,我会返回约定的错误代码。
例如:

$.ajax({
   url: 'http://test:port/project/list;jsessionid=' + jessionid,
   ...
})

但我不认为这样是好的工作。这是非常麻烦的,在客户端,我需要检查每个响应代码是正确的或不为每个请求。有什么更好的方法来解决这个问题?
顺便说一下,客户端(浏览器+ AJAX )和服务器(Springmvc)是分开的。

相关问题