Posted In: Spring, Spring Boot, Spring Security

Example – Spring Boot – Security – Default Basic Authentication

 

Note

Basic authentication transmits the password as plain text so it should only really be used over an encrypted transport layer such as HTTPS when used in enterprise application.
 

1. Create Spring boot project. Refer create-eclipse-spring-boot-application-step-by-step

 
 

2. Choose security checkbox or add following maven entry

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-security</artifactId>
</dependency>

 
 

3. Start spring boot application

Find following log. It is printed at log level info and above.

Using default security password: 264a55ac-a392-408f-b8a1-f1c5e519f493

.......

org.springframework.security.web.header.HeaderWriterFilter@3569edd5, 
org.springframework.security.web.authentication.logout.LogoutFilter@4b61d0c6,
org.springframework.security.web.authentication.www.BasicAuthenticationFilter@1f14f20c, 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter@42d236fb,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@19f9d595, 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter@5d28bcd5,
org.springframework.security.web.session.SessionManagementFilter@430fa4ef, 
org.springframework.security.web.access.ExceptionTranslationFilter@cd7f1ae,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1bd81830]

If you do not see the log change the log level using following entry in application.properties

logging.level.org.springframework.web=DEBUG

 
 

4. Create simple rest service

@RestController
public class ExampleService {
	@RequestMapping(value = "/employee/list",
	        consumes = "application/json",
	        method = { RequestMethod.POST })
	public @ResponseBody Object getEmployeeList(
	        ServletRequest req, ServletResponse res,
	        @RequestBody String requestJson) throws Exception {
		System.out.println("getEmployeeList() called");
		return "{'response' : 'success'}";
	}
...............

 
 

5. Now try the service http://localhost:8080/employee/list. You should get unauthorized error

{
  "timestamp": 1487267495668,
  "status": 401,
  "error": "Unauthorized",
  "message": "Bad credentials",
  "path": "/employee/list"
}

 
 

6. Add basic authentication information. Use same password found in step 3

Using default security password: 264a55ac-a392-408f-b8a1-f1c5e519f493

 

6a. Using POSTMAN browser plugin

 

6b. Using curl

Convert username:password to BASE64 using online tools like base64encode
user:264a55ac-a392-408f-b8a1-f1c5e519f493
Pass it to curl in header –header “Authorization:Basic dXNlcjoyNjRhNTVhYy1hMzkyLTQwOGYtYjhhMS1mMWM1ZTUxOWY0OTM=”

curl -X POST http://localhost:8080/employee/list --header "Content-Type:application/json" --header "Authorization:Basic dXNlcjoyNjRhNTVhYy1hMzkyLTQwOGYtYjhhMS1mMWM1ZTUxOWY0OTM=" -d "{}"

 

6c. Using MockMvc

Note – This test will always fail as Spring Boot will regenerate password each time you restart the server. Set your own password to run this test.

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class Example201720ApplicationTests {

	@Autowired
	private MockMvc mvc;

	@Test
	public void contextLoads() {
	}

	@Test
	public void testBasicAuth() throws Exception {
		mvc.perform(MockMvcRequestBuilders.post("/employee/list")
		.header("Authorization", "Basic dXNlcjoyNjRhNTVhYy1hMzkyLTQwOGYtYjhhMS1mMWM1ZTUxOWY0OTM=")
		.accept(MediaType.TEXT_HTML)
		.contentType(MediaType.APPLICATION_JSON)
		.content("{}")).andExpect(status().isOk())
		.andExpect(content().string(
		equalTo("{'response' : 'success'}")));
	}
}

 

6d. Using RestTemplate

	@Test
	public void testBasicAuth() throws Exception {
		String url = "http://localhost:8080/employee/list";
		RestTemplate rest = new RestTemplate(
			new HttpComponentsClientHttpRequestFactory());
		rest.setErrorHandler(new RestErrorHandler());
		rest.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
		rest.getMessageConverters().add(new StringHttpMessageConverter());
		HttpHeaders headers = new HttpHeaders();
		headers.add("Authorization",
		        "Basic dXNlcjoyNjRhNTVhYy1hMzkyLTQwOGYtYjhhMS1mMWM1ZTUxOWY0OTM=");
		headers.setContentType(MediaType.APPLICATION_JSON);
		HttpEntity<String> entity = new HttpEntity<String>("{}",
		        headers);
		ResponseEntity<String> response = rest.exchange(url,
		        HttpMethod.POST, entity, String.class);
	}
package com.example.springapp;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler;

public class RestErrorHandler implements ResponseErrorHandler {
	@Override
	public void handleError(ClientHttpResponse response)
	        throws IOException {
		System.out.println("inside handleError()");
	}

	@Override
	public boolean hasError(ClientHttpResponse response)
	        throws IOException {
		System.out.println("inside hasError()");
		if(response.getStatusCode() != HttpStatus.OK) {
			return true;
		}
		return false;
	}
}

 
 

7. Now service should return valid 200 response

 
 

Tags: , ,

by , on February 16th, 2017

  • Categories