SpringSecurity解決跨域問題,在SpringBoot整合SprinSecurity中如何用前后端分離Ajax登錄


先說說SpringSecurity如何實現前后端分離Ajax登錄?

  今天使用SpringBoot整合SpringSecurity中想使用Ajax替代SpringSecurit的Form表單提交,在這里我們的提交方式還是使用表單提交

http.formLogin().loginProcessingUrl("/authentication/form")
loginProcessingUrl方法表示你登錄請求的地址,在這里SpringSecurity默認登錄頁面地址是/login ,填寫了username與password 上送的地址就是loginProcessingUrl方法指定的地址,
如果你想使用Ajax登錄+Token驗證,或者是移動端不得不這樣做的時候,那么你就不用管SpringSecurity的默認登錄地址啦,只需要注意 在Ajax請求的時候 登錄名必須是username字段
密碼必須是 password字段 登錄提交的地址就是loginProcessingUrl方法指定的路徑/authentication/form
因為在SpringSecurity中處理賬號密碼登錄的過濾器是UsernamePasswordAuthenticationFilter 而這個登錄處理類里面寫死了這兩個字段的名稱,如下圖源碼中所見:
public class UsernamePasswordAuthenticationFilter extends
        AbstractAuthenticationProcessingFilter {
    // ~ Static fields/initializers
    // =====================================================================================

    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";

我測試的前端登錄代碼如下:

$.ajax({
        url:"http://127.0.0.1/authentication/form",
        timeout : 20000,
        type:"post",
        dataType:"json",
        data:{
            username:"088358",password:"123"
        },
        success:function(data){
              alert('ok')
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert("1 異步調用返回失敗,XMLHttpResponse.readyState:"+XMLHttpRequest.readyState);
            alert("2 異步調用返回失敗,XMLHttpResponse.status:"+XMLHttpRequest.status);
            alert("3 異步調用返回失敗,textStatus:"+textStatus);
            alert("4 異步調用返回失敗,errorThrown:"+errorThrown);
        }
    })

后端在執行登錄成功之后處理代碼

后端在執行登錄成功之后會回調AuthenticationSuccessHandler攔截器的onAuthenticationSuccess方法,我們只需要寫一個類集成AuthenticationSuccessHandler就可以重寫這個方法來生成token返回給前端了,Token如何生成,請看上一章jwtToken的使用 https://www.cnblogs.com/langjunnan/p/12464791.html ,這章不細說

@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        // 登錄成功之后
        List<Object> functs = (List<Object>) authentication.getAuthorities();// 當前功能列表
        String loginName = authentication.getName();// 登錄名
        Users obj = (Users) authentication.getPrincipal();// 用戶信息
        String token = JwtUtil.createToken(loginName, functs, obj);// 生成token
        response.setHeader(JwtUtil.TOKEN_HEADER, JwtUtil.TOKEN_PREFIX + token);
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);
        PrintWriter pw = response.getWriter();
        DTO dto = new DTO<>();
        dto.setCode("000000");
        dto.setMessage("認證通過");
        String json=JsonUtil.set(dto);
        System.out.println(json);
        pw.println(json); // println 等於pw.flush()+pw.close();
    
    }
}

代碼是沒有問題的,但是由於跨域的問題Ajax是調用不成功的,

SpringSecurity中的跨域問題

之前寫項目都是自己定義一個過濾器來解決跨域問題,但是這次過濾器不好用了,只能把跨域資源配置到SpringSecurity中了

代碼如下

http.cors().configurationSource(CorsConfigurationSource())//允許跨域訪問
/*跨域原*/
    private CorsConfigurationSource CorsConfigurationSource() {
        CorsConfigurationSource source =   new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");    //同源配置,*表示任何請求都視為同源,若需指定ip和端口可以改為如“localhost:8080”,多個以“,”分隔;
        corsConfiguration.addAllowedHeader("*");//header,允許哪些header,本案中使用的是token,此處可將*替換為token;
        corsConfiguration.addAllowedMethod("*");    //允許的請求方法,PSOT、GET等
        ((UrlBasedCorsConfigurationSource) source).registerCorsConfiguration("/**",corsConfiguration); //配置允許跨域訪問的url
        return source;
    }

 

 

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM