Java Libraries
Use JAR files which are listed below:
antlr-2.7.7.jar
avro-1.7.5.jar
cglib-2.2.jar
classmate-1.0.0.jar
com.springsource.org.aopalliance-1.0.0.jar
commons-codec-1.6.jar
commons-compress-1.5.jar
commons-dbcp-1.4.jar
commons-io-2.4.jar
commons-lang-2.6.jar
commons-logging.jar
commons-pool-1.6.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.4.Final.jar
hibernate-core-4.3.1.Final.jar
hibernate-entitymanager-4.3.1.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
hibernate-search-analyzers-4.5.0.CR1.jar
hibernate-validator-5.1.1.Final.jar
hibernate-validator-annotation-processor-5.1.1.Final.jar
hibernate-validator-cdi-5.1.1.Final.jar
jackson-core-asl-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
jandex-1.1.0.Final.jar
javassist-3.18.1-GA.jar
javax.servlet.jsp.jstl-1.2.2.jar
javax.servlet.jsp.jstl-api-1.2.1.jar
jboss-logging-3.1.3.GA.jar
jboss-logging-annotations-1.2.0.Beta1.jar
jms-1.1.jar
jsr250-api-1.0.jar
jta-1.1.jar
lucene-analyzers-3.6.2.jar
lucene-core-3.6.2.jar
lucene-grouping-3.6.2.jar
lucene-highlighter-3.6.2.jar
lucene-kuromoji-3.6.2.jar
lucene-memory-3.6.2.jar
lucene-misc-3.6.2.jar
lucene-phonetic-3.6.2.jar
lucene-smartcn-3.6.2.jar
lucene-spatial-3.6.2.jar
lucene-spellchecker-3.6.2.jar
lucene-stempel-3.6.2.jar
mysql-connector-java-5.0.8.jar
paranamer-2.3.jar
persistence-api-1.0.2.jar
slf4j-api-1.7.7.jar
solr-analysis-extras-3.6.2.jar
solr-core-3.6.2.jar
solr-solrj-3.6.2.jar
spring-aop-3.2.3.RELEASE.jar
spring-beans-4.0.6.RELEASE.jar
spring-context-4.0.6.RELEASE.jar
spring-context-support-4.0.6.RELEASE.jar
spring-core-4.3.3.RELEASE.jar
spring-expression-4.0.6.RELEASE.jar
spring-jdbc-4.0.6.RELEASE.jar
spring-orm-4.0.6.RELEASE.jar
spring-oxm-4.0.6.RELEASE.jar
spring-security-config-4.1.3.RELEASE.jar
spring-security-core-4.1.3.RELEASE.jar
spring-security-web-4.1.3.RELEASE.jar
spring-tx-4.0.6.RELEASE.jar
spring-web-4.0.6.RELEASE.jar
spring-webmvc-4.0.6.RELEASE.jar
validation-api-1.1.0.Final.jar
xml-apis-1.0.b2.jar
Create Server Project
Create Dynamic Web Project in Eclipse and add the below configuration to the web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<session-config>
<session-timeout>1</session-timeout>
</session-config>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Security -->
<servlet>
<servlet-name>api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>api</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<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>
Spring Restful Web Services Confiagurtion File
Create api-servlet.xml file contains configuration for Spring Restful Web Services
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-4.0.xsd" >
</beans>
Security Configuration File
Create spring-security.xml file contains configuration for security
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="demo.*" />
<mvc:annotation-driven />
<!-- Rest authentication entry point configuration -->
<http auto-config="true"
use-expressions="true"
entry-point-ref="restAuthenticationEntryPoint">
<intercept-url pattern="/api/**" />
<sec:form-login authentication-success-handler-ref="mySuccessHandler"
authentication-failure-handler-ref="myFailureHandler" />
<logout />
</http>
<!-- Connect the custom authentication success handler -->
<beans:bean id="mySuccessHandler"
class="demo.security.RestAuthenticationSuccessHandler" />
<!-- Using default failure handler -->
<beans:bean id="myFailureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler" />
<!-- Authentication manager -->
<authentication-manager alias="authenticationManager">
<authentication-provider>
<user-service>
<user name="acc1" password="123" authorities="ROLE_SUPER_ADMIN,ROLE_ADMIN,ROLE_USER" />
<user name="acc2" password="123" authorities="ROLE_ADMIN,ROLE_USER" />
<user name="acc3" password="123" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
<!-- Enable the annotations for defining the secure role -->
<global-method-security secured-annotations="enabled" />
</beans:beans>
Project Structure
Security Classes
Create demo.security package in server project. This package contain classes need for security in Spring Restful Web Services. Create classes: RestAuthenticationEntryPoint.java and RestAuthenticationSuccessHandler.java as below
RestAuthenticationEntryPoint.java
package demo.security;
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("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
AuthenticationException authenticationException) throws IOException, ServletException {
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
RestAuthenticationSuccessHandler.java
package demo.security;
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 RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
private RequestCache requestCache = new HttpSessionRequestCache();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws ServletException, IOException {
SavedRequest savedRequest = requestCache.getRequest(request, response);
if (savedRequest == null) {
clearAuthenticationAttributes(request);
return;
}
String targetUrlParam = getTargetUrlParameter();
if (isAlwaysUseDefaultTargetUrl() || (targetUrlParam != null && StringUtils.hasText(request.getParameter(targetUrlParam)))) {
requestCache.removeRequest(request, response);
clearAuthenticationAttributes(request);
return;
}
clearAuthenticationAttributes(request);
}
public void setRequestCache(RequestCache requestCache) {
this.requestCache = requestCache;
}
}
Create Rest API Controller
Create Rest API Controller provides text/plain data for the client
package demo.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.*;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("demo")
public class DemoController {
@RequestMapping(
value = "work1",
method = RequestMethod.GET,
produces = { MimeTypeUtils.TEXT_PLAIN_VALUE }
)
public ResponseEntity<String> work1() {
try {
String content = "Work 1";
return new ResponseEntity<String>(content, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
}
@Secured({ "ROLE_SUPER_ADMIN" })
@RequestMapping(
value = "work2",
method = RequestMethod.GET,
produces = { MimeTypeUtils.TEXT_PLAIN_VALUE }
)
public ResponseEntity<String> work2() {
try {
String content = "Work 2";
return new ResponseEntity<String>(content, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
}
@Secured({ "ROLE_SUPER_ADMIN", "ROLE_ADMIN" })
@RequestMapping(
value = "work3",
method = RequestMethod.GET,
produces = { MimeTypeUtils.TEXT_PLAIN_VALUE }
)
public ResponseEntity<String> work3() {
try {
String content = "Work 3";
return new ResponseEntity<String>(content, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
}
@Secured({ "ROLE_SUPER_ADMIN", "ROLE_ADMIN", "ROLE_USER" })
@RequestMapping(
value = "work4",
method = RequestMethod.GET,
produces = { MimeTypeUtils.TEXT_PLAIN_VALUE }
)
public ResponseEntity<String> work4() {
try {
String content = "Work 4";
return new ResponseEntity<String>(content, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<String>(HttpStatus.BAD_REQUEST);
}
}
}
Testing Web API
Access Web API use the following url: http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work1
Output
Work 1
Access restful web services use the following url: http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work2
Output
Access restful web services use the following url: http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work3
Output
Access restful web services use the following url: http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work4
Output
Consume Rest API Controller from Console Application
Create Java Project in Eclipse
Create DemoRestClientModel
DemoRestClientModel class contain methods call Web API
package models;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.apache.commons.codec.binary.Base64;
public class DemoRestClientModel {
private String BASE_URL = "http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/";
private RestTemplate restTemplate = new RestTemplate();
private String username = "acc2";
private String pasword = "123";
private HttpHeaders getHeaders() {
String plainCredentials = this.username + ":" + this.pasword;
String base64Credentials = new String(Base64.encodeBase64(plainCredentials.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Credentials);
return headers;
}
public ResponseEntity<String> work1() {
return restTemplate.exchange(BASE_URL + "work1", HttpMethod.GET, null, String.class);
}
public ResponseEntity<String> work2() {
return restTemplate.exchange(BASE_URL + "work2", HttpMethod.GET, null, String.class);
}
public ResponseEntity<String> work3() {
HttpEntity<String> request = new HttpEntity<String>(getHeaders());
return restTemplate.exchange(BASE_URL + "work2", HttpMethod.GET, request, String.class);
}
public ResponseEntity<String> work4() {
HttpEntity<String> request = new HttpEntity<String>(getHeaders());
return restTemplate.exchange(BASE_URL + "work3", HttpMethod.GET, request, String.class);
}
public ResponseEntity<String> work5() {
HttpEntity<String> request = new HttpEntity<String>(getHeaders());
return restTemplate.exchange(BASE_URL + "work4", HttpMethod.GET, request, String.class);
}
}
Run Application
package main;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import models.DemoRestClientModel;
public class Main {
public static void main(String[] args) {
DemoRestClientModel demoRestClientModel = new DemoRestClientModel();
try {
System.out.println("Test with work1 web method");
ResponseEntity<String> responseEntity1 = demoRestClientModel.work1();
HttpStatus HttpStatus1 = responseEntity1.getStatusCode();
System.out.println("\tStatus Code: " + HttpStatus1);
String result1 = responseEntity1.getBody();
System.out.println("\tResult: " + result1);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
System.out.println("Test with work2 web method without account");
ResponseEntity<String> responseEntity2 = demoRestClientModel.work2();
HttpStatus HttpStatus2 = responseEntity2.getStatusCode();
System.out.println("\tStatus Code: " + HttpStatus2);
String result2 = responseEntity2.getBody();
System.out.println("\tResult: " + result2);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
System.out.println("Test with acc2 have roles: admin and user access work2 web method");
ResponseEntity<String> responseEntity3 = demoRestClientModel.work3();
HttpStatus HttpStatus3 = responseEntity3.getStatusCode();
System.out.println("\tStatus Code: " + HttpStatus3);
String result3 = responseEntity3.getBody();
System.out.println("\tResult: " + result3);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
System.out.println("Test with acc2 have roles: admin and user access work3 web method");
ResponseEntity<String> responseEntity4 = demoRestClientModel.work4();
HttpStatus HttpStatus4 = responseEntity4.getStatusCode();
System.out.println("\tStatus Code: " + HttpStatus4);
String result4 = responseEntity4.getBody();
System.out.println("\tResult: " + result4);
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
System.out.println("Test with acc2 have roles: admin and user access work4 web method");
ResponseEntity<String> responseEntity5 = demoRestClientModel.work5();
HttpStatus HttpStatus5 = responseEntity5.getStatusCode();
System.out.println("\tStatus Code: " + HttpStatus5);
String result5 = responseEntity5.getBody();
System.out.println("\tResult: " + result5);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
Output
Test with work1 web method
Status Code: 200
Result: Work 1
Test with work2 web method without account
GET request for "http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work2" resulted in 401 (Unauthorized); invoking error handler
401 Unauthorized
Test with acc2 have roles: admin and user access work2 web method
WARNING: GET request for "http://localhost:8086/SecurityInWebServiceSpringFramework/api/demo/work2" resulted in 403 (Forbidden); invoking error handler
403 Forbidden
Test with acc2 have roles: admin and user access work3 web method
Status Code: 200
Result: Work 3
Test with acc2 have roles: admin and user access work4 web method
Status Code: 200
Result: Work 4