Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security, Rest Authentication and CSRF

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

like image 511
Jonathan Lebrun Avatar asked Feb 18 '14 13:02

Jonathan Lebrun


People also ask

How do I enable CSRF in Spring boot REST API?

Enable CSRF Protection With REST API If our project requires CSRF protection, we can send the CSRF token with a cookie by using CookieCsrfTokenRepository in a custom WebSecurityConfigurerAdapter. After restarting the app, our requests receive HTTP errors, which means that CSRF protection is enabled.

Is CSRF needed for REST API?

Enabling cross-site request forgery (CSRF) protection is recommended when using REST APIs with cookies for authentication. If your REST API uses the WCToken or WCTrustedToken tokens for authentication, then additional CSRF protection is not required.

How CSRF is implemented in Spring Security?

To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.

Is CSRF enabled by default in Spring Security?

As of Spring Security 4.0, CSRF protection is enabled by default with XML configuration.


1 Answers

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

like image 84
bsmk Avatar answered Sep 30 '22 16:09

bsmk