2016-04-13 1 views
4

Ich entwickle eine Anwendung mit Extjs-6 mit Spring 4. Meine Anwendung ist Ruhe.
aktiviere ich CORS Herkunft wie folgt:Wie meldet man sich bei der Federsicherung mit Ext.Ajax an?

public class CorsFilter extends OncePerRequestFilter { 

    private static final String ORIGIN = "Origin"; 


    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
     throws ServletException, IOException { 

     response.addHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Credentials", "true"); 
     response.addHeader("Access-Control-Max-Age", "10"); 

     String reqHead = request.getHeader("Access-Control-Request-Headers"); 

     if (!StringUtils.isEmpty(reqHead)) { 
      response.addHeader("Access-Control-Allow-Headers", reqHead); 
     } 

     if (request.getMethod().equals("OPTIONS")) { 
      try { 
       response.getWriter().print("OK"); 
       response.getWriter().flush(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     } else{ 
      filterChain.doFilter(request, response); 
     } 
    } 
} 

Filter config:

<security:http use-expressions="true"> 
    ... 
    <sec:custom-filter ref="CorsFilter" before="HEADERS_FILTER"/> 
</security:http> 

und die Bohne:

<bean id="CorsFilter" class="..." /> 

Ich möchte Benutzer loging mit einer AJAX-Anfrage. Ich teste Ajax Anfrage mit Advanced REST client und . Die Ergebnisse der Erweiterungen sind wie folgt:

enter image description here

enter image description here

Ext Ajax-Request-Code ist wie folgt:

Ext.Ajax.request({ 
    url: "http://localhost/Calk/j_spring_security_check", 
//  params: { 
//   "j_username": "ali", 
//   "j_password": "123456" 
//  }, 
    params: "j_username=ali&j_password=123456", 
    headers: { 
     "Content-Type": "application/x-www-form-urlencoded" 
    }, 
    method: "POST", 
    success: function(){...}, 
    failure: function(){...} 
}); 

Als ich die Anfrage senden, es 200 OK bekommen, und ich init die Anwendung auf der Client-Seite, und senden Sie einige Anfragen, um einige Daten zu erhalten. Aber Server für alle Anfragen erhalten 401 Unauthorized.

Was ist das Problem?

Wichtiges Update:

logining Anfrage ist wie folgt:

enter image description here

Server gesetzt Cookie als Antwort und autorisierte Datenanforderung erhalten ist wie folgt:

enter image description here

Warum?

+0

Haben Sie versucht mit 'params: form.getValues ​​()'? – qmateub

+0

ja, das Ergebnis ist wie oben. –

+0

Das Problem ist, dass die Request-Methode "OPTIONS" verwendet wird, die immer ohne die Parameter gesendet wird, die Sie für die Authentifizierung benötigen. [Überprüfen Sie hier, warum diese Methode verwendet wird] (https://www.sencha.com/forum/showthread.php?95656-how-to-disable-Ajax.request-method-quot-OPTIONS-quot&p=452480&viewfull=1# post452480). – Alexander

Antwort

1

Spring Security arbeitet wie folgt:
Wenn eine Anfrage von einem Client kein JSessionID-Cookie enthält, setzt Spring die Sitzung dieses Clients zurück und setzt eine ungültige Sitzung für ihn. Dann wird die nächste Anfrage mit dieser ungültigen Sitzung gesendet.

So müssen Sie in allen Ext Ajax Anfragen Cookie setzen. Ich denke, einige gleichzeitige Ajax-Anfragen senden kein Cookie. Um Cookie in allen Ajax-Anfragen zu stellen, können Sie dieses Ereignis hinzu:

Ext.Ajax.on("beforerequest",function(con){ 
    con.setUseDefaultXhrHeader(false); 
    con.setWithCredentials(true); 
} 

Diese Funktion ausgeführt wird, bevor alle Ihre AJAX-Anfragen zu senden.

2

Der Grund für Ihren Fehler ist, dass Sie eine domänenübergreifende Anfrage stellen. Ich denke, dass Ihre Javascript-Anwendung in anderen Port ausgeführt wird, während Ihr Anwendungsserver auf 8084 ausgeführt wird.

Damit dies funktioniert, müssen Sie die CORS-Unterstützung für Ihre Anwendung aktivieren. Hier ist, wie Sie das tun können.

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 

    @Override 
    public void addCorsMappings(CorsRegistry registry) { 
     registry.addMapping("/**"); 
    } 
} 

Follow this link für ausführliche Erklärung. In den meisten Fällen sollte dies für Sie funktionieren. Wenn sich die Federsicherung noch immer beschweren sollte, müssen Sie eventuell einen Filter für die Federsicherung hinzufügen.Sie können dies tun, indem following this answer

public class CorsFilter extends OncePerRequestFilter { 

    private static final String ORIGIN = "Origin"; 


    @Override 
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 
     throws ServletException, IOException { 

     if (request.getHeader(ORIGIN) == null || request.getHeader(ORIGIN).equals("null")) { 
      response.addHeader("Access-Control-Allow-Origin", "*"); 
      response.setHeader("Access-Control-Allow-Credentials", "true"); 
      response.addHeader("Access-Control-Max-Age", "10"); 

      String reqHead = request.getHeader("Access-Control-Request-Headers"); 

      if (!StringUtils.isEmpty(reqHead)) { 
       response.addHeader("Access-Control-Allow-Headers", reqHead); 
      } 
     } 
     if (request.getMethod().equals("OPTIONS")) { 
      try { 
       response.getWriter().print("OK"); 
       response.getWriter().flush(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     } else{ 
      filterChain.doFilter(request, response); 
     } 
    } 
} 

Konfigurieren Sie den Filter für Sicherheit

<security:http use-expressions="true" .... > 
    ... 
    //your other configs 
    <sec:custom-filter ref="corsFilter" before="HEADERS_FILTER"/> 
</security:http> 

Setzen Sie die Filter als Bean

<bean id="corsFilter" class="<<location of the CORS filter class>>" /> 
+0

Ich habe einige Geschäfte, die alle Daten vom gleichen Webserver bekommen, ich setze CORS Config und es erhalten alle Daten korrekt. Aber nur Login-Anfrage funktioniert nicht richtig –

+0

Dann versuchen Sie den Sicherheitsfilter, aktualisiert die Antwort. – JChap

+0

Ich habe meinen Code entsprechend Ihrer Antwort aktualisiert. Wenn ich Login Ajax Request sende, bekomme der Server '200 OK' (wenn ich einen falschen Benutzer/Pass sende, erhält er' 401 Authorized'). Wenn der Benutzer sich erfolgreich angemeldet hat, erhalten Sie einige Daten usign ajax, aber im nächsten Anfrage-Server bekommen Sie '401 Authorized'. –

0

ich glaube, das Problem ist, dass die Session-Cookie gesetzt wird /Calk/ Pfad, während der Ajax-Anruf von /Workspace/Calk/ gemacht wird. Sie müssen also herausfinden, wo der Sitzungs-Cookie-Pfad im Frühjahr konfiguriert ist, und ihn so ändern, dass er nur / ist.

Ich habe nicht Frühling Sicherheit, sondern von einer schnellen Suche this und this Fragen scheinen darauf hinzudeuten, dass Sie den Weg in web.xml ändern können:

<web-app> 
    <session-config> 
     <cookie-config> 
      <path>/</path> 
     </cookie-config> 
    </session-config> 
</web-app>