import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
public class HttpClientFactoryBean implements InitializingBean, FactoryBean ...{
private HttpClient httpClient;
private String username;
private String password;
private String authenticationHost;
private String authenticationRealm;
public HttpClient getHttpClient() ...{
return httpClient;
}
public void setHttpClient(HttpClient httpClient) ...{
this.httpClient = httpClient;
}
public String getUsername() ...{
return username;
}
public void setUsername(String username) ...{
this.username = username;
}
public String getPassword() ...{
return password;
}
public void setPassword(String password) ...{
this.password = password;
}
public String getAuthenticationHost() ...{
return authenticationHost;
}
public void setAuthenticationHost(String authenticationHost) ...{
this.authenticationHost = authenticationHost;
}
public String getAuthenticationRealm() ...{
return authenticationRealm;
}
public void setAuthenticationRealm(String authenticationRealm) ...{
this.authenticationRealm = authenticationRealm;
}
public void afterPropertiesSet() throws Exception ...{
//构造HttpClient对象
httpClient=new HttpClient();
httpClient.getState().setAuthenticationPreemptive(true);
Credentials credentials=new UsernamePasswordCredentials(username,password);
httpClient.getState().setCredentials(authenticationRealm,authenticationHost,credentials);
}
public Object getObject() throws Exception ...{
return httpClient;
}
public Class getObjectType() ...{
return HttpClient.class;
}
public boolean isSingleton() ...{
return true;
}
}
我们在访问Spring HTTP 远程方法的时候,没有任何的安全机制,只要知道服务接口和WSDL,都可以访问,本文讲结合Tomcat的角色机制,为HTTP远程方法调用加入安全验证机制
服务端:
服务接口:
public interface HelloWorld ...{
public String getMessage();
}
public class SimpleHelloWorld implements HelloWorld ...{
public String getMessage() ...{
return "hello world secure http";
}
}
配置文件:httpInvoker-servlet.xml(WEB-INF下)
<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-2.0.xsd">
<bean id="defaultHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
</bean>
<bean name="/helloWorld" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service">
<bean class="ch16.SecureHTTP.SimpleHelloWorld"/>
</property>
<property name="serviceInterface">
<value>ch16.SecureHTTP.HelloWorld</value>
</property>
</bean>
</beans>
web.xml
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/httpInvoker-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>httpInvoker</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>httpInvoker</servlet-name>
<url-pattern>/http/*</url-pattern>
</servlet-mapping>
<!-- HTTP 安全性配置 -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure HTTP Services</web-resource-name>
<url-pattern>/http/helloWorld</url-pattern> <!-- spring配置文件中的bean name -->
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>ProSpringStudyWeb</realm-name>
</login-config>
<security-role>
<role-name>manager</role-name>
</security-role>
主主要是的最后一段,这里使用了tomcat-user.xml文件中定义的manager角色作为验证,至于这个角色的用户名和密码,可以在tomcat-user.xml中配置,如下:
<tomcat-users>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="admin" password="1234" roles="admin,manager"/>
</tomcat-users>
启动服务器,运行http://localhost:81/ProSpringStudyWeb/http/helloWorld (具体访问路径跟你你自己的project)
会出现一个要求输入用户名和密码的提示窗口,到此,服务端配置成功了,下面我们看客户端的实现
客户端:
部署一个安全的HTTP服务是件很容易的事情,而访问他就不那么简单了,就拿HttpInvokerProxyFactoryBean来说,这个Bean可以由内置的JDK HTTP支持,也可由commons httpClient project来支持,内置的JDK HTTP不支持HTTP基本验证,这意味着你需要使用HttpClient去访问一个安全服务,配置HttpInvokerProxyFactoryBean,我们需要使用HttpClient的CommonsHttpInvokerRequestExecutor的实例中对httpInvokerRequestExecutor的特征进行下一步设置
这将事情变得复杂了。CommonsHttpInvokerRequestExecutor不允许你将用户名和密码作为属性设置,但是他确实允许你访问HttpClient这个类所产生的实例,这是HttpClient project的核心。但是,你不可能使用Spring的依赖注入配置HttpClient的基本认证功能的凭证(因为不是setter/getter属性),所以,我们使用了Spring的FactoryBea返回一个HttpClient的恰当配置的实例,关于FactoryBean的介绍,请参考http://blog.csdn.net/daryl715/archive/2007/07/06/1681055.aspx,我们用一个HttpClientFactoryBean类来完成HttpClient实例的装配
HttpClientFactoryBean
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
public class HttpClientFactoryBean implements