Spring Rest service Security using Basic authentication


Lets discuss Spring Rest service security with basic authentication


we can make our rest services more secure by using Spring security feature.

whenever the client makes a request to secured rest service using its end point,Spring security will intercept the request to authenticate the user.

if the user is authenticated , control flows to actual rest service else it will be redirected to EntryPoint which in turn sends a 401 response to client.

rest_security_basic_flow


Lets implement the same step by step

Create a new Maven Web project in eclipse (Refer Spring MVC Hello World project for the same)

Project structure


rest_security_basic_proj_structure

Step 1

Update pom.xml with below dependencies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>SpringRestServiceSecurityBasic</groupId>
    <artifactId>SpringRestServiceSecurityBasic</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringRestServiceSecurityBasic Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <org.springframework.version>4.2.0.RELEASE</org.springframework.version>
        <spring-security.version>3.2.7.RELEASE</spring-security.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <!-- Jackson JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.5</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>${spring-security.version}</version>
        </dependency>
 
    </dependencies>
    <build>
        <finalName>SpringRestServiceSecurityBasic</finalName>
    </build>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>SpringRestServiceSecurityBasic</groupId>
	<artifactId>SpringRestServiceSecurityBasic</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringRestServiceSecurityBasic Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<org.springframework.version>4.2.0.RELEASE</org.springframework.version>
		<spring-security.version>3.2.7.RELEASE</spring-security.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${org.springframework.version}</version>
		</dependency>
		<!-- Jackson JSON -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.8.5</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-core</artifactId>
			<version>${spring-security.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-web</artifactId>
			<version>${spring-security.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-config</artifactId>
			<version>${spring-security.version}</version>
		</dependency>

	</dependencies>
	<build>
		<finalName>SpringRestServiceSecurityBasic</finalName>
	</build>
</project>


We have added dependencies for Spring mvc ,spring security , Jackson and Junit in the above pom file.

Step 2

Update web.xml file with Dispatcher servlet and spring security filter

we have defined a dispatcher servlet in web.xml and mapped it by the URL pattern “/”

So just like any other servlet in web application,any request matching with the given pattern i.e “/” will be redirected to “Dispatcher servlet”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <display-name>Archetype Created Web Application</display-name>
  
   <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
            /WEB-INF/spring-beans.xml,
            /WEB-INF/spring-security.xml
        </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- Loads Spring Security configuration file -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-beans.xml,
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>
 
    <!-- Spring Security filter -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
 
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
</web-app>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
  <display-name>Archetype Created Web Application</display-name>
  
   <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
            /WEB-INF/spring-beans.xml,
            /WEB-INF/spring-security.xml
        </param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
    <!-- Loads Spring Security configuration file -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring-beans.xml,
            /WEB-INF/spring-security.xml
        </param-value>
    </context-param>
 
    <!-- Spring Security filter -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
 
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
</web-app>


We have provided the spring configuration file name to create and load the spring beans while starting the server.

Also we have provided Spring security config file to load the security related configuration.

we have also added filter for spring security which will delegate the request for authentication before processing the request.

Step 3

Create a Spring beans config file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
 
    <context:component-scan base-package="com.kb" />
    <mvc:annotation-driven />
     
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
 
    <context:component-scan base-package="com.kb" />
    <mvc:annotation-driven />
     
</beans>

Step 4

Create the spring security config file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.2.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
 
    <!-- Rest authentication entry point configuration -->
    <http use-expressions="true" entry-point-ref="customAuthenticationEntryPoint">
        <intercept-url pattern="/rest/**" access="hasAnyRole('ROLE_ADMIN','ROLE_REST')"/>
        <form-login authentication-success-handler-ref="successHandler"
            authentication-failure-handler-ref="failureHandler" />
        <http-basic/>
        <logout />
    </http>
 
    <!-- Connect the custom authentication success handler -->
    <beans:bean id="successHandler"
        class="com.kb.rest.authentication.CustomSavedRequestAwareAuthenticationSuccessHandler" />
    <!-- Using default failure handler -->
    <beans:bean id="failureHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
 
    <!-- Authentication manager -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider>
        <user-service>
            <user name="admin" password="admin" authorities="ROLE_ADMIN"/>
            <user name="rest" password="rest" authorities="ROLE_REST"/>
            <user name="user" password="user" authorities="ROLE_USER"/>
         </user-service>
        </authentication-provider>
    </authentication-manager>
 
</beans:beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:sec="http://www.springframework.org/schema/security"
    xsi:schemaLocation="
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-3.2.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
 
    <!-- Rest authentication entry point configuration -->
    <http use-expressions="true" entry-point-ref="customAuthenticationEntryPoint">
        <intercept-url pattern="/rest/**" access="hasAnyRole('ROLE_ADMIN','ROLE_REST')"/>
        <form-login authentication-success-handler-ref="successHandler"
            authentication-failure-handler-ref="failureHandler" />
 		<http-basic/>
        <logout />
    </http>
 
    <!-- Connect the custom authentication success handler -->
    <beans:bean id="successHandler"
        class="com.kb.rest.authentication.CustomSavedRequestAwareAuthenticationSuccessHandler" />
    <!-- Using default failure handler -->
    <beans:bean id="failureHandler"
        class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
 
    <!-- Authentication manager -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider>
        <user-service>
            <user name="admin" password="admin" authorities="ROLE_ADMIN"/>
            <user name="rest" password="rest" authorities="ROLE_REST"/>
            <user name="user" password="user" authorities="ROLE_USER"/>
         </user-service>
        </authentication-provider>
    </authentication-manager>
 
</beans:beans>

In the above spring security xml file we have defined the entry point as “customAuthenticationEntryPoint” with the success and failure handler.

In Spring, Entry point is used to redirect the non authenticated request to get the authentication by displaying login page.

In REST Service, using entry point for displaying login page doesn’t make any sense as Rest Services most of the times will be called by some client interfaces like RestTemplate rather than a browser request.

So it is better to send the response as 401 Unauthorized when the request comes without the authentication rather than redirecting to login page to get the authentication.

success and failure handler

By default, form login will return a successful authentication with a 301 (MOVED PERMANENTLY) status code ,this makes sense in case of web applications.
In case of RESTful web service ,the expected response for a successful authentication is 200 OK.

This can be done by injecting a custom authentication success handler in the form login filter, by replacing the default one.

we have not defined any custom handler for failure handler because the default spring provider class SimpleUrlAuthenticationFailureHandler will take care of returning 401 status code.

we have also defined authentication provider as user service with set of users along with their credentials and roles defined in it.

we are granting access to Rest services only for those users whose Role is either ROLE_ADMIN or ROLE_REST as configured above.

Step 5

Create custom authentication Entry pont

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.kb.rest.authentication;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
 
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{
 
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
            throws IOException, ServletException {
        System.out.println("Executing commence method due to failed Authentication");
        response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized Access!!" );
        
    }
 
}
package com.kb.rest.authentication;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint{

	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
			throws IOException, ServletException {
		System.out.println("Executing commence method due to failed Authentication");
		response.sendError( HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized Access!!" );
		
	}

}


we have defined CustomAuthenticationEntryPoint with implementation for commence method.

This entry point is called whenever the request is missing the authentication or having invalid authentication.
and in that case, we are sending the unauthorized response to the client.

Step 6

Create Custom Authentication Success Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.kb.rest.authentication;
 
import java.io.IOException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;
 
public class CustomSavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
    
    private RequestCache requestCache = new HttpSessionRequestCache();
    
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
        Authentication authentication) throws IOException, ServletException {
     final SavedRequest savedRequest = requestCache.getRequest(request, response);
     
     if (savedRequest == null) {
         clearAuthenticationAttributes(request);
         return;
     }
     final String targetUrlParameter = getTargetUrlParameter();
     if (isAlwaysUseDefaultTargetUrl()
             || (targetUrlParameter != null && StringUtils.hasText(request
                     .getParameter(targetUrlParameter)))) {
         requestCache.removeRequest(request, response);
         clearAuthenticationAttributes(request);
         return;
     }
 
     clearAuthenticationAttributes(request);
 
 }
 
 public void setRequestCache(final RequestCache requestCache) {
     this.requestCache = requestCache;
 }
}
package com.kb.rest.authentication;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.util.StringUtils;

public class CustomSavedRequestAwareAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{
	
	private RequestCache requestCache = new HttpSessionRequestCache();
	
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
		Authentication authentication) throws IOException, ServletException {
	 final SavedRequest savedRequest = requestCache.getRequest(request, response);
	 
     if (savedRequest == null) {
         clearAuthenticationAttributes(request);
         return;
     }
     final String targetUrlParameter = getTargetUrlParameter();
     if (isAlwaysUseDefaultTargetUrl()
             || (targetUrlParameter != null && StringUtils.hasText(request
                     .getParameter(targetUrlParameter)))) {
         requestCache.removeRequest(request, response);
         clearAuthenticationAttributes(request);
         return;
     }

     clearAuthenticationAttributes(request);

 }

 public void setRequestCache(final RequestCache requestCache) {
     this.requestCache = requestCache;
 }
}

we have defined a custom authentication success handler by overriding onAuthenticationSuccess method

we have just removed the redirection logic in this success handler.

Step 7

Create rest service which we want to secure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.kb.rest.controllers;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.kb.rest.model.User;
 
@Controller
@RequestMapping("/rest")
public class RestController {
 
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public @ResponseBody User getUserForId(@PathVariable ("id") int id) {
        User user = new User();
        user.setId(id);
        user.setName("John");
        user.setAge(45);
        return user;
    }
}
package com.kb.rest.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kb.rest.model.User;

@Controller
@RequestMapping("/rest")
public class RestController {

	@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
	public @ResponseBody User getUserForId(@PathVariable ("id") int id) {
		User user = new User();
		user.setId(id);
		user.setName("John");
		user.setAge(45);
		return user;
	}
}

we have exposed one method for retrieving the user based on id.

Step 8

Create Rest client using spring rest template without credentials

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.kb.rest.client;
 
import org.springframework.web.client.RestTemplate;
 
import com.kb.rest.model.User;
 
public class GetUserClient {
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        final String url = "http://localhost:8080/SpringRestServiceSecurityBasic/rest/user/1";
        User user = restTemplate.getForObject(url, User.class);
        System.out.println("User retrieved details : ");
        System.out.println(user.getName() + " " + user.getAge() + " " + user.getId());
 
    }
}
package com.kb.rest.client;

import org.springframework.web.client.RestTemplate;

import com.kb.rest.model.User;

public class GetUserClient {
	public static void main(String[] args) {
		RestTemplate restTemplate = new RestTemplate();
		final String url = "http://localhost:8080/SpringRestServiceSecurityBasic/rest/user/1";
		User user = restTemplate.getForObject(url, User.class);
		System.out.println("User retrieved details : ");
		System.out.println(user.getName() + " " + user.getAge() + " " + user.getId());

	}
}
Step 9

Create Rest client using spring rest template with valid credentials

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.kb.rest.client;
 
import java.util.Arrays;
 
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.RestTemplate;
 
import com.kb.rest.model.User;
 
public class GetUserClientWithCredentials {
    
    /*
     * Add HTTP Authorization header, using Basic-Authentication to send user-credentials.
     */
    private static HttpHeaders getHeaders(){
        String plainCredentials="admin:admin";
        String base64Credentials = new String(Base64.encode(plainCredentials.getBytes()));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + base64Credentials);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        return headers;
    }
    
    public static void main(String[] args) {
        RestTemplate restTemplate = new RestTemplate();
        final String url = "http://localhost:8080/SpringRestServiceSecurityBasic/rest/user/1";
        HttpEntity<String> request = new HttpEntity<String>(getHeaders());
        ResponseEntity<User> userResponse = restTemplate.exchange(url,HttpMethod.GET,request, User.class);
        System.out.println("User retrieved details : ");
        User user =userResponse.getBody();
        System.out.println(user.getName() + " " + user.getAge() + " " + user.getId());
 
    }
 
 
}
package com.kb.rest.client;

import java.util.Arrays;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.web.client.RestTemplate;

import com.kb.rest.model.User;

public class GetUserClientWithCredentials {
	
	/*
     * Add HTTP Authorization header, using Basic-Authentication to send user-credentials.
     */
    private static HttpHeaders getHeaders(){
        String plainCredentials="admin:admin";
        String base64Credentials = new String(Base64.encode(plainCredentials.getBytes()));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + base64Credentials);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        return headers;
    }
    
	public static void main(String[] args) {
		RestTemplate restTemplate = new RestTemplate();
		final String url = "http://localhost:8080/SpringRestServiceSecurityBasic/rest/user/1";
		HttpEntity<String> request = new HttpEntity<String>(getHeaders());
		ResponseEntity<User> userResponse = restTemplate.exchange(url,HttpMethod.GET,request, User.class);
		System.out.println("User retrieved details : ");
		User user =userResponse.getBody();
		System.out.println(user.getName() + " " + user.getAge() + " " + user.getId());

	}


}

Step 10

Build and deploy the project

Step 11

Let’s access the rest service using different clients

access below url in Browser

http://localhost:8080/SpringRestServiceSecurityBasic/rest/user/1

rest_security_basic_browser_output.jpg


Run GetUserClient.java which does not have credentials

output


Run GetUserClientWithCredentials.java which has valid credentials

output

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on