
Secure Restful Web Service using Spring Security Part 1
Posted by johnnyren in Johnny ren's Blog on May 16, 2013 8:52:43 PMWhy Restful?
- Restful is popular alternative to SOAP web service and It is easy to use.
How do you secure your restful web service?
- How do you protect server side resources to allow only certain authenticated users to access? Because each restful request is a stateless request, so you can’t use standard login page to authenticate a user anymore.
- The solution is to use Http Authentication header and spring security framework.
- There are many ways to use Spring Security to authenticate user request. In this paper I am going to show you how to use FilterSecurityInterceptor to authenticate user requests
Sequence Diagram
- This diagram show Spring Security can protect your Java server side resource.
- The Client makes a request to the server side service.
- Spring FilterSecurityInterceptor intercepts the request and extract the Authentication header.
- Spring FilterSecurityInterceptor calls AuthercationManger to authticate the user.
- Spring FilterSecurityInterceptor use AccessManager to decide if the system is going to allow the user to access the protected resource.
Spring Configuration
- Web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<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>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Mvc-dispatcher-servlet.xml
<context:component-scan base-package="com.johnnyweb.stockWatcher.controller" />
<mvc:annotation-driven />
<security:authentication-manager>
<security:authentication-provider>
<security:user-service id="userService">
<security:user name="gwtrest" password="gwtrest" authorities="customer" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<security:http create-session="stateless" use-expressions="true">
<security:intercept-url pattern="/**"
access="hasAnyRole('customer')" />
<security:http-basic />
</security:http>
Spring controller
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody List<StockPrice> getStocks( @RequestParam(value = "q", required = false) final String q ) {
String[] stockSymbols = q.split(" ");
ArrayList<StockPrice> stockPriceList= new ArrayList<StockPrice>();
for (String stockSymbol : stockSymbols) {
Random rnd = new Random();
double price = rnd.nextDouble() * MAX_PRICE;
double change = price * MAX_PRICE_CHANGE * (rnd.nextDouble() * 2f - 1f);
StockPrice stockPrice = new StockPrice();
stockPrice.setSymbol(stockSymbol);
stockPrice.setPrice(price);
stockPrice.setChange(change);
stockPriceList.add(stockPrice);
}
return stockPriceList;
}
Test your restful service using FIrefox RestClient
Comments