2

dies ist mein feder security.xml:Spring Security für Ruhe-Anwendung. POST Rückkehr immer 403 Code

<security:http pattern="/eklienci/**" 
     authentication-manager-ref="authenticationManager" entry-point-ref="restAuthenticationEntryPoint" 
     create-session="stateless"> 
     <security:intercept-url pattern="/eklienci/**" 
      access="hasAnyAuthority('ADMIN','USER','VIEWER')" /> 
     <form-login 
      authentication-success-handler-ref="mySuccessHandler" 
      authentication-failure-handler-ref="myFailureHandler" 
     /> 
     <security:custom-filter ref="restServicesFilter" 
      before="PRE_AUTH_FILTER" /> 
    </security:http> 
    <!-- other stuff --!> 
    <beans:bean id="restAuthenticationEntryPoint" 
     class="pl.aemon.smom.config.RestAuthenticationEntryPoint" /> 
    <!-- Filter for REST services. --> 
    <beans:bean id="restServicesFilter" 
    class="pl.aemon.smom.config.RestUsernamePasswordAuthenticationFilter"> 
    <beans:property name="postOnly" value="true" /> 
    <beans:property name="authenticationManager" ref="authenticationManager" /> 
    <beans:property name="authenticationSuccessHandler" ref="mySuccessHandler" /> 
</beans:bean> 

Das ist mein RestUsernamePasswordAuthenticationFilter ist:

public class RestUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter 
{ 

    @Autowired 
    private CustomAuthenticationProvider authenticationProvider; 


    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { 

     Enumeration<String> names = request.getHeaderNames(); 
     while(names.hasMoreElements()) 
     { 
      System.out.println(names.nextElement()); 
     } 
     String username = obtainUsername(request); 
     String password = obtainPassword(request); 
     System.out.println("Username " + username + " password: " + password); 
     if(username!=null) 
     { 
      username = username.trim(); 
     } 

     UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); 

     // Allow subclasses to set the "details" property 
     setDetails(request, authRequest); 
     return authenticationProvider.authenticateRest(authRequest); 

//  System.out.println(auth.toString()); 
//  return auth; 
    } 



    @Override 
    protected String obtainPassword(HttpServletRequest request) { 
     return request.getHeader("password"); 
    } 

    @Override 
    protected String obtainUsername(HttpServletRequest request) { 
     return request.getHeader("username"); 
    } 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 
      ServletException { 

     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 

     Authentication auth = attemptAuthentication(httpRequest, httpResponse); 
     SecurityContextHolder.getContext().setAuthentication(auth); 

     chain.doFilter(request, response); 

    } 
} 

Und das ist meine RestController Methoden

@RestController 
@RequestMapping("/eklienci") 
public class EklientRestController 
{ 
    @RequestMapping(value="/get/{eklientid}") 
    public Eklient get(@PathVariable String eklientid) 
    { 
     return userService.findById(eklientid); 
    } 

    @RequestMapping(value = "/add", method = RequestMethod.POST, produces="application/json", consumes="application/json") 
    @ResponseBody 
    public String add(@RequestBody String json) 
    { 
     System.out.println(json); 
     Eklient pj = new Eklient(); 
     ObjectMapper mapper = new ObjectMapper(); 
     try 
     { 
      pj = mapper.readValue(json, Eklient.class); 
      return mapper.writeValueAsString(pj); 
     } catch (JsonParseException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (JsonMappingException e) 
     { 
     // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return "Error"; 
    } 
} 

Wenn i versuche,/get/{eklientid} aufzurufen, es funktioniert immer gut. Alle GET-Aufrufe geben immer mindestens Informationen über den UNARTHORIZED-Zugriff (401) zurück und ich sehe Protokolle von RestUsernamePasswordAuthenticationFilter.

Aber wenn ich jeden POST Aufruf versuchen (zB/eklienci/add} meine Anwendung immer 403 Code zurückgibt und producde keine log. Was ist der Grund? Wie es zu beheben?

+0

Sie erwähnt GET-Anfragen funktioniert gut, wenn Rückkehr Statuscode 401, was bedeutet es? Erfolgt dieser Anruf vor oder nach der Authentifizierung? – Igor

Antwort

3

CSRF aktiviert wird Wenn Sie die CSRF-Header nicht in Ihre REST-Aufrufe eingefügt haben, können Sie die CSFF-Dateien in Ihrer security.xml (vorübergehend!) schließen, um das Problem zu beheben Vor allem müssen Sie die CSRF headers in Ihre REST-Aufrufe und <sec:csrfInput/> JSPs-Tags für alle Client-Server-Aufrufe hinzufügen.Fünf, zusätzliche Klassen, die ich in meinem Open-Source-Projekt implementieren musste, vielleicht nützlich für Sie:

  1. CsrfSecurityRequestMatcher CSRF für bestimmte POSTs/PUTs usw. deaktivieren, die keine Autorisierung erfordern. Wie konfiguriert here in meiner security.xml.
  2. CustomAccessDeniedHandlerImpl, um CSRF 403, die aus Sitzungstimeouts resultieren, stattdessen auf eine Anmeldeseite zu leiten.
-1

Deaktivieren Sie den CSRF-Schutz. Es ist nicht erforderlich, wenn Sie create-session="stateless" haben.

<security:http ...> 
    <security:csrf disabled="true"/> 
    <!-- the rest same as before --> 
</security:http> 
+0

Nein, nicht wahr: http://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html#csrf-and-stateless-browser-applications –

+0

@GlenMazza Unsicher in einigen speziellen Fälle, aber das OP scheint weder Authentifizierungs-Cookie noch Basisauthentifizierung zu verwenden. – holmis83

Verwandte Themen