Spring Security, Rest Authentication and CSRF

java, rest, spring, spring-security

Solution

I have been playing with spring security and spring boot REST application and I created my own MapCsrfTokenRepository that I used instead of default HttpSessionCsrfTokenRepository.

Then you can enable csrf for your rest URIs with

http.csrf().csrfTokenRepository(tokenRepository)

The main idea is to return new CSRF_TOKEN when client access /login resource with GET, because no csrf token is needed for GET. And then client has to use this token in next calls.

Example is on github

Problem

I would like use authentication with my application. I hava a Spring MVC app and Spring Security applied. Against browser, it is working fine. It means, I authenticate a user to my app and use web page. Now, I want to use rest. I added on my unsecure controller method @ResponseBody and I receive response in json. But how to connect to my application with user and password with RestTemplate ? My code in RestClient is (for test) : ``` public void unsecureProfileTest() { String url = articleServiceUrl + "unsecure/profile/test.json"; url = articleServiceUrl + "secure/profile/wiew.json"; HttpEntity<Object> entity = new HttpEntity<Object>(getHeaders("user:userpassword")); Object s = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class); } static HttpHeaders getHeaders(String auth) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.TEXT_HTML)); byte[] encodedAuthorisation = Base64.encode(auth.getBytes()); headers.add("Authorization", "Basic " + new String(encodedAuthorisation)); return headers; } ``` My SecurityConfig : ``` @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.authorizeRequests().antMatchers("/*").permitAll().and() .formLogin().successHandler(successHandler) .defaultSuccessUrl("/").failureHandler(failureHandler) .failureUrl("/login?error=true").permitAll().and().logout() .permitAll(); http.authorizeRequests().antMatchers("/resources/**").permitAll(); http.authorizeRequests().antMatchers("/welcome").permitAll(); http.authorizeRequests().antMatchers("/unsecure/**").permitAll(); http.authorizeRequests().antMatchers("/secure/*").authenticated(); http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated(); } ``` The result is : Access is denied. I guess the problem comming from authentication from restTemplate but how can I authenticate ? My second question is regarding csrf who is disabled but I want to enable it (my forms use it) I'm using Spring 4.0 and Spring Security 3.2 EDIT I updated my code with ``` String url = articleServiceUrl + "unsecure/profile/test.json"; url = articleServiceUrl + "secure/profile/wiew.json"; HttpEntity<Object> entity = new HttpEntity<Object>(getHeaders("{user:userpassword, password:userpassword}")); Object s = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class); ``` I receive a code `302` EDIT 18022014 - 16:46 I updated to ``` String url = articleServiceUrl + "login?username=user&password=userpassword"; HttpEntity entity restTemplate;exchange(url, HTTPMethod.POST,null, HttpEntity.class) system.out.println(entity); ``` In log of web server, I received a success message (see userdetails on "user"). Now, I would like use authentication to access to other url ("secure/profile/view.json") How to keep authentication ? Thank you

Original source