When a Web Service is protected by Spring security, and we try to access that Web Service, we are presented with a login page to enter our credentials. After we provide our credentials, this information is stored as part of the session and sent back and forth between the browser and the server in a cookie.
However this is not the way it works with a non-browser, standalone client (like a mobile app) – for obvious reasons.
This note describes a thick client. User requires to login into the thick client. On successful authentication the user’s credentials are stored with the client. When the client accesses the Web Service, the web server responds to the client with the login page. Then the client presents the credentials, and submits it back to the web server.
Thus accessing a Web Service secured by Spring Security is a two-step process.
This note primarily describes the client. Some server-side config files are shown for information.
Follows are relevant code snippets for this scenario.
Comments are provided in bold.
On the Server side
Follows are some standard code snippets to secure a URL pattern with Spring Security with a username and password. Please refer to Spring Security documentation for detailed instructions and samples.
In web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml,
/WEB-INF/spring-security.xml
</param-value>
</context-param>
……..
……..
<!-- Spring Security -->
<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>
In spring-security.xml
<beans:beans xmlns="http://ift.tt/1gJEsAP;
xmlns:beans="http://ift.tt/GAfaRz;
xmlns:xsi="http://ift.tt/Atvu06;
xsi:schemaLocation="http://ift.tt/GArMu6
http://ift.tt/QEDs1e
http://ift.tt/1c8inpe
http://ift.tt/1igcnCk;
<!--Web Services with the pattern “/rest/vp/” will be secured -->
<http auto-config="true">
<intercept-url pattern="/rest/vp/**" access="ROLE_USER" />
</http>
<!—The username and password to be provided is “vpUser” and “vp123” -->
<authentication-manager>
<authentication-provider>
<user-service>
<user name="vpUser" password="vp123" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>
</beans:beans>
In mvc-dispatcher-servlet.xml
<beans xmlns="http://ift.tt/GAfaRz;
xmlns:context="http://ift.tt/GAfaRB;
xmlns:mvc="http://ift.tt/1gSwL9o; xmlns:xsi="http://ift.tt/Atvu06;
xsi:schemaLocation="
http://ift.tt/GArMu6
http://ift.tt/QEDs1e
http://ift.tt/GArMu7
http://ift.tt/QEDs1k
http://ift.tt/1bHqwjR
http://ift.tt/1gVzA7d;
<context:component-scan base-package="com.devices.middleware.webservice" />
<mvc:annotation-driven />
</beans>
On the Mobile Client side
// This is the object that we will populate from the JSON object
//returned by the Web Service
List<AlarmBean> alarmBeanList = new ArrayList<AlarmBean>();
// The username and password authenticated to the client, and required for
//the Web Service
//String urlParameters=
// "j_username="+userBean.getUsername()+"&j_password="+userBean.getPassword();
String urlParameters="j_username="+”vpUser” +"&j_password="+”vp123”;
// When Spring Security presents the login page, that page gets submitted to this link.
// i.e. - /j_spring_security_check
String strSpringAuthURL = "http://hostname/j_spring_security_check";
//This is the REST Web Service to be invoked
String strWebSvc = "http://hostname/rest/vp/alarm/11";
try {
// Create the URL object with the Web Service url
URL url = new URL(strWebSvc);
System.out.println("strWebSvc "+strWebSvc);
// Invoke the URL
HttpURLConnection conn = (HttpURLConnection) url
.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setInstanceFollowRedirects(false);
// ************* IMP *************
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setUseCaches (false);
//HTTP Response codes are
// 200 is OK
// 302 is Redirect
// When the secured Web Service is requested, the web server directs
// to the login page and sends a 302 Response code
if (conn.getResponseCode() == 302) {
System.out.println(" Response code is " + conn.getResponseCode());
String newUrl = conn.getHeaderField("Location");
// Get the cookie. It has the value of the original Web Service URL.
//In a browser scenario, after successful authentication, it would’ve
//automatically re-directed to the WS URL
String cookies = conn.getHeaderField("Set-Cookie");
//conn = (HttpURLConnection) new URL(strSpringAuthURL +
// ";jsessionid=" + J_SESSION_ID).openConnection();
conn = (HttpURLConnection) new URL(strSpringAuthURL).openConnection();
//Pass on the cookie
conn.setRequestProperty("Cookie", cookies);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("POST");
DataOutputStream wr1 = new DataOutputStream(conn.getOutputStream ());
//Pass on the credentials
wr1.writeBytes(urlParameters);
wr1.flush();
wr1.close();
//System.out.println("Redirect to URL : " + strSpringAuthURL
// + ";jsessionid=" + J_SESSION_ID);
System.out.println("Redirected to URL : " + strSpringAuthURL );
System.out.println("Response code from Spring Auth URL is " +
conn.getResponseCode());
//Get the Web Service URL from the http header
String strOrigWSUrl = conn.getHeaderField("Location");
String cookies1 = conn.getHeaderField("Set-Cookie");
//conn = (HttpURLConnection) new URL(strOrigWSUrl +
// ";jsessionid=" + J_SESSION_ID).openConnection();
// Connection is made to the original Web Service URL that we want
conn = (HttpURLConnection) new URL(strOrigWSUrl).openConnection();
// ************* IMP *************
// The cookies that we received after authentication is passed here again.
conn.setRequestProperty("Cookie", cookies1);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setInstanceFollowRedirects(false);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setUseCaches (false);
System.out.println("Redirect to URL strOrigWSUrl : " + strOrigWSUrl);
// We get a 200 Response code now
System.out.println(" Response code 555 is " + conn.getResponseCode());
} //end-if for the condition where we checked if the Response code was 302
//if the response code was not 302 above at the “if” check for the response code,
//and was 200 (assumed, not checked here),
//code would’ve continued here-forward
// Reading the JSON output returned by the Web Service
// And populating the AlarmBean object
BufferedReader br = new BufferedReader(
new InputStreamReader((conn.getInputStream())));
String line;
while ((line = br.readLine()) != null) {
JSONArray jsa = new JSONArray(line);
for (int i = 0; i < jsa.length(); i++) {
JSONObject jo = (JSONObject) jsa.get(i);
AlarmBean alarmBean = new AlarmBean(jo
.getInt("alarmId"), jo.getString("timestamp"),
jo.getString("duration"), jo
.getString("meterName"), jo
.getString("alarmType"), jo
.getString("status"), jo
.getInt("dcId"), jo
.getInt("count"), jo
.getString("deviceId"), jo
.getInt("buildingId"), jo
.getBoolean("disabled"), jo
.getString("location"), jo
.getString("dc"), jo
.getString("buildingName"), jo
.getInt("acknowledgedBy"), jo
.getString("ackUserName"), jo
.getString("acknowledgedOn"), jo
.getString("thresholdValue"), jo
.getString("actualValue"));
alarmBeanList.add(alarmBean);
}
The post Navigating Spring Security from thick Client to REST Webservice appeared first on ViralPatel.net.
via ViralPatel.net http://ift.tt/1gWwD7N
No comments:
Post a Comment
If you have any question please let me know