STEP 1:- Open Eclipse and Create Dynamic Web Project named SpringSecurityRESTBasicAuthentication
STEP 2:- Make sure you use Target Runtime as Apache Tomcat 7.0.
STEP 3:- copy below jars to WEB-INF/lib folder.
The Authentication Manager is not the focus of this tutorial, so we are using an in memory manager with the user and password defined in plaintext.
STEP 6 :- Map Spring configuration files in /WebContent/WEB-INF/web.xml file as below :-
http://localhost:8080/SpringSecurityRESTBasicAuthentication/
STEP 13 :- Consuming The Secured Application The curl command is our go to tool for consuming the secured application.
First, let’s try to request the /api/users without providing any security credentials:
Now, let’s request the same resource – /api/users – but provide the credentials to access it as well:
STEP 14 :- Further Configuration – The Entry Point By default, the BasicAuthenticationEntryPoint provisioned by Spring Security returns a full html page for a 401 Unauthorized response back to the client. This html representation of the error renders well in a browser, but it not well suited for other scenarios, such as a REST API where a json representation may be preferred. The namespace is flexible enough for this new requirement as well – to address this – the entry point can be overridden:
Please share us on social media if you like the tutorial.
STEP 2:- Make sure you use Target Runtime as Apache Tomcat 7.0.
STEP 3:- copy below jars to WEB-INF/lib folder.
- aopalliance-1.0.jar
- aspectjrt-1.8.4.jar
- commons-io-2.4.jar
- commons-logging-1.2.jar
- jackson-annotations-2.6.0.jar
- jackson-core-2.6.0.jar
- jackson-databind-2.6.0.jar
- jtds.jar
- log4j-1.2.17.jar
- spring-aop-4.1.4.RELEASE.jar
- spring-beans-4.1.4.RELEASE.jar
- spring-context-4.1.4.RELEASE.jar
- spring-core-4.1.4.RELEASE.jar
- spring-dao-2.0.8.jar
- spring-expression-4.1.4.RELEASE.jar
- spring-jdbc-4.1.4.RELEASE.jar
- spring-security-config-4.0.2.RELEASE.jar
- spring-security-core-4.0.2.RELEASE.jar
- spring-security-oauth2-2.0.8.RELEASE.jar
- spring-security-taglibs-4.0.2.RELEASE.jar
- spring-security-web-4.0.2.RELEASE.jar
- spring-web-4.1.4.RELEASE.jar
- spring-webmvc-4.1.4.RELEASE.jar
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.tutorialsdesk.controllers" /> <context:component-scan base-package="com.tutorialsdesk.services" /> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="suffix" value=".jsp" /> </bean> <bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/> </beans>STEP 5:- Create Spring security configuration file. /WebContent/WEB-INF/spring-security.xml
<?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:oauth="http://www.springframework.org/schema/security/oauth2" xmlns:security="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <security:global-method-security pre-post-annotations="enabled"/> <security:http use-expressions="true"> <security:intercept-url access="hasRole('ROLE_VERIFIED')" pattern="/api/**"/> <security:intercept-url pattern='/*' access='permitAll'/> <security:logout logout-success-url="/"/> <security:session-management session-fixation-protection="newSession"> <security:concurrency-control max-sessions="1"/> </security:session-management> <security:http-basic /> </security:http> <security:authentication-manager> <security:authentication-provider> <security:user-service> <security:user name="test" password="test" authorities="ROLE_VERIFIED"/> </security:user-service> </security:authentication-provider> </security:authentication-manager> </beans>What is relevant here is the <http-basic> element inside the main <http> element of the configuration – this is enough to enable Basic Authentication for the entire application.
The Authentication Manager is not the focus of this tutorial, so we are using an in memory manager with the user and password defined in plaintext.
STEP 6 :- Map Spring configuration files in /WebContent/WEB-INF/web.xml file as below :-
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>SpringSecurityRESTBasicAuthentication</display-name> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spring-security.xml </param-value> </context-param> <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>STEP 7 :- Create Controller Class.
- Package: com.tutorialsdesk.controller
- Filename: RestController.java
package com.tutorialsdesk.controllers; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.tutorialsdesk.models.Employee; import com.tutorialsdesk.services.EmployeeService; @Controller @RequestMapping() public class RestController { @Autowired EmployeeService employeeService; @RequestMapping(value = "api/users", method = RequestMethod.GET) @ResponseBody public List<Employee> list() { System.out.println("RestController.list()"); return employeeService.getEmployeesList(); } }STEP 9 :- Create Model Class.
- Package: com.tutorialsdesk.model
- Filename: Employee.java
package com.tutorialsdesk.models; import java.io.Serializable; public class Employee implements Serializable{ private static final long serialVersionUID = 5088863992478607917L; private Integer id; private String firstName; private String lastName; private String email; public Employee(Integer id, String firstName, String lastName, String email) { super(); this.id = id; this.firstName = firstName; this.lastName = lastName; this.email = email; } public Employee() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public static long getSerialversionuid() { return serialVersionUID; } @Override public String toString() { return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]"; } }STEP 10 :- Create Service Interface and Class.
- Package: com.tutorialsdesk.services
- Filename: EmployeeService.java
package com.tutorialsdesk.services; import java.util.List; import com.tutorialsdesk.models.Employee; public interface EmployeeService { public List<Employee> getEmployeesList(); }
- Package: com.tutorialsdesk.services
- Filename: EmployeeServiceImpl.java
package com.tutorialsdesk.services; import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Service; import com.tutorialsdesk.models.Employee; @Service public class EmployeeServiceImpl implements EmployeeService { @Override public List<Employee> getEmployeesList() { List<Employee> employeeList = new ArrayList<Employee>(); employeeList.add(new Employee(1, "Prince", "Sethi", "prince@gmail.com")); employeeList.add(new Employee(2, "Rambir", "Singh", "rambir@gmail.com")); employeeList.add(new Employee(3, "Vishnu", "Jangid", "vishnu@gmail.com")); return employeeList; } }STEP 11 :- Create jsp file in /WebContent/WEB-INF folder
- Filename: index.jsp
<html> <body> <h2>Spring REST Security Basic Authentication</h2> <a href="http://localhost:8080/SpringSecurityRESTBasicAuthentication/api/users">Get Users List</a> <br/> <br/> Or use CURL command <br/> <br/> curl -i --user test:test http://localhost:8080/SpringSecurityRESTBasicAuthentication/api/users </body> </html>STEP 12 :- Run your project enter below URL in your browser
http://localhost:8080/SpringSecurityRESTBasicAuthentication/
STEP 13 :- Consuming The Secured Application The curl command is our go to tool for consuming the secured application.
First, let’s try to request the /api/users without providing any security credentials:
curl -i http://localhost:8080/SpringSecurityRESTBasicAuthentication/api/usersWe get back the expected 401 Unauthorized and the Authentication Challenge:
HTTP/1.1 401 Unauthorized Server: Apache-Coyote/1.1 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-XSS-Protection: 1; mode=block X-Frame-Options: DENY X-Content-Type-Options: nosniff Set-Cookie: JSESSIONID=D3E07DD1EE9DA030C14C958CF207D5A2; Path=/SpringSecurityRES TBasicAuthentication/; HttpOnly WWW-Authenticate: Basic realm="Spring Security Application" Content-Type: text/html;charset=utf-8 Content-Language: en Content-Length: 1061 Date: Fri, 24 Jun 2016 06:17:52 GMT <html><head><title>Apache Tomcat/7.0.55 - Error report</title><style><!--H1 {fon t-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size: 22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525 D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;backgro und-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;col or:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:w hite;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;backgroun d:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - Full authentica tion is required to access this resource</h1><HR size="1" noshade="noshade"><p>< b>type</b> Status report</p><p><b>message</b> <u>Full authentication is required to access this resource</u></p><p><b>description</b> <u>This request requires H TTP authentication.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/7.0. 55</h3></body></html>The browser would interpret this challenge and prompt us for credentials with a simple dialog, but since we’re using curl, this isn’t the case.
Now, let’s request the same resource – /api/users – but provide the credentials to access it as well:
curl -i --user test:test http://localhost:8080/SpringSecurityRESTBasicAuthentication/api/usersNow, the response from the server is 200 OK along with a Cookie:
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 X-XSS-Protection: 1; mode=block X-Frame-Options: DENY X-Content-Type-Options: nosniff Set-Cookie: JSESSIONID=299E6E6B73DB9E94E4AAC0AD01F7F258; Path=/SpringSecurityRES TBasicAuthentication/; HttpOnly Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Fri, 24 Jun 2016 06:19:25 GMT [{"id":1,"firstName":"Prince","lastName":"Sethi","email":"prince@gmail.com"},{"i d":2,"firstName":"Rambir","lastName":"Singh","email":"rambir@gmail.com"},{"id":3 ,"firstName":"Vishnu","lastName":"Jangid","email":"vishnu@gmail.com"}]From the browser, the application can be consumed normally – the only difference is that a login page is no longer a hard requirement since all browsers support Basic Authentication and use a dialog to prompt the user for credentials.
STEP 14 :- Further Configuration – The Entry Point By default, the BasicAuthenticationEntryPoint provisioned by Spring Security returns a full html page for a 401 Unauthorized response back to the client. This html representation of the error renders well in a browser, but it not well suited for other scenarios, such as a REST API where a json representation may be preferred. The namespace is flexible enough for this new requirement as well – to address this – the entry point can be overridden:
<security:http-basic entry-point-ref="customAuthenticationEntryPoint" />The new entry point is defined as a standard bean:
- Package: com.tutorialsdesk.security
- Filename: CustomAuthenticationEntryPoint.java
package com.tutorialsdesk.security; import java.io.IOException; import java.io.PrintWriter; 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.authentication.www.BasicAuthenticationEntryPoint; import org.springframework.stereotype.Component; @Component public class CustomAuthenticationEntryPoint extends BasicAuthenticationEntryPoint{ @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx) throws IOException, ServletException { response.addHeader("WWW-Authenticate", "Basic realm=" + getRealmName() + ""); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); PrintWriter writer = response.getWriter(); writer.println("HTTP Status 401 - " + authEx.getMessage()); } @Override public void afterPropertiesSet() throws Exception { setRealmName("Baeldung"); super.afterPropertiesSet(); } }By writing directly to the HTTP Response we now have full control over the format of the response body. Keep visiting TutorialsDesk for more tutorials and practical programming examples on Spring MVC. Hope we are able to explain you Spring MVC Security REST Basic Authentication Example, if you have any questions or suggestions please write to us using contact us form.
Please share us on social media if you like the tutorial.
Blogger Comment
Facebook Comment