在按照网上的例子进行配置用户名令牌的例子,在server端的回调函数中获取的password 却一直是空,搜索了好半天,才找到(这个是MD5加密的):
WSPasswordCallback 的passwordType属性和password 属性都为null,你只能获得用户名(identifier),一般这里的逻辑是使用这个用户名到数据库中查询其密码,然后再设置到password 属性,WSS4J 会自动比较客户端传来的值和你设置的这个值。你可能会问为什么这里CXF 不把客户端提交的密码传入让我们在ServerPasswordCallbackHandler 中比较呢?这是因为客户端提交过来的密码在SOAP 消息中已经被加密为MD5 的字符串,如果我们要在回调方法中作比较,那么第一步要做的就是把服务端准备好的密码加密为MD5 字符串,由于MD5 算法参数不同结果也会有差别,另外,这样的工作CXF 替我们完成不是更简单吗?
根据上面说的,我获取的password 为null,所以这里就不用自己判断密码了,只要验证用户名后,在设置密码就可以自动验证了,代码如下:
01 |
public class ServerPasswordCallback implements CallbackHandler { |
03 |
public void handle(Callback[] callbacks) throws IOException, |
04 |
UnsupportedCallbackException { |
05 |
WSPasswordCallback pc = (WSPasswordCallback) callbacks[ 0 ]; |
06 |
String pw = pc.getPassword(); |
07 |
String idf = pc.getIdentifier(); |
08 |
System.out.println( "password:" +pw); |
09 |
System.out.println( "identifier:" +idf); |
10 |
if (idf.endsWith( "admin" )){ |
11 |
pc.setPassword( "admin" ); |
以下是源代码:
HelloWorld.java
1 |
package com.mms.webservice; |
2 |
import javax.jws.WebService; |
4 |
public interface HelloWorld { |
5 |
String sayHi(String text); |
HelloWorldImpl.java
01 |
package com.mms.webservice; |
02 |
import javax.annotation.Resource; |
03 |
import javax.jws.WebService; |
04 |
import javax.servlet.http.HttpServletRequest; |
05 |
import javax.servlet.http.HttpSession; |
06 |
import javax.xml.ws.WebServiceContext; |
07 |
import javax.xml.ws.handler.MessageContext; |
08 |
import org.apache.cxf.transport.http.AbstractHTTPDestination; |
11 |
public class HelloWorldImpl implements HelloWorld { |
12 |
public String sayHi(String text) { |
13 |
return "Hello " + text; |
ServerPasswordCallback.java
01 |
package com.mms.webservice.test; |
02 |
import java.io.IOException; |
03 |
import java.util.HashMap; |
05 |
import javax.security.auth.callback.Callback; |
06 |
import javax.security.auth.callback.CallbackHandler; |
07 |
import javax.security.auth.callback.UnsupportedCallbackException; |
08 |
import org.apache.ws.security.WSPasswordCallback; |
09 |
import org.apache.ws.security.WSSecurityException; |
11 |
public class ServerPasswordCallback implements CallbackHandler { |
13 |
private Map<String, String> passwords = new HashMap<String, String>(); |
15 |
public ServerPasswordCallback() { |
16 |
passwords.put( "admin" , "admin" ); |
17 |
passwords.put( "test" , "test" ); |
20 |
public void handle(Callback[] callbacks) throws IOException, |
21 |
UnsupportedCallbackException { |
22 |
System.out.println( "server:callbacks.length-" +callbacks.length); |
23 |
for ( int i = 0 ; i < callbacks.length; i++) { |
24 |
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; |
25 |
if (!passwords.containsKey(pc.getIdentifier())) |
27 |
throw new WSSecurityException( "user not match" ); |
28 |
} catch (WSSecurityException e) { |
31 |
String pass = passwords.get(pc.getIdentifier()); |
ClientPasswordCallback .java
01 |
package com.mms.client; |
02 |
import java.io.IOException; |
03 |
import java.util.HashMap; |
05 |
import javax.security.auth.callback.Callback; |
06 |
import javax.security.auth.callback.CallbackHandler; |
07 |
import javax.security.auth.callback.UnsupportedCallbackException; |
08 |
import org.apache.ws.security.WSPasswordCallback; |
09 |
import org.apache.ws.security.WSSecurityException; |
11 |
public class ClientPasswordCallback implements CallbackHandler { |
13 |
private Map<String, String> passwords = new HashMap<String, String>(); |
15 |
public ClientPasswordCallback() { |
16 |
passwords.put( "admin" , "admin" ); |
17 |
passwords.put( "test" , "test" ); |
20 |
public void handle(Callback[] callbacks) throws IOException, |
21 |
UnsupportedCallbackException { |
22 |
System.out.println( "client:callbacks.length-" +callbacks.length); |
23 |
for ( int i = 0 ; i < callbacks.length; i++) { |
24 |
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; |
25 |
int usage = pc.getUsage(); |
26 |
if (!passwords.containsKey(pc.getIdentifier())) |
28 |
throw new WSSecurityException( "user not exists " ); |
29 |
} catch (WSSecurityException e) { |
32 |
String pass = passwords.get(pc.getIdentifier()); |
33 |
if (usage == WSPasswordCallback.USERNAME_TOKEN && pass != null ) { |
34 |
System.out.println( "client:pass" +pass); |
web.xml
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
< web-app version = "2.5" |
03 |
xmlns = "http://java./xml/ns/javaee" |
04 |
xmlns:xsi = "http://www./2001/XMLSchema-instance" |
05 |
xsi:schemaLocation="http://java./xml/ns/javaee |
06 |
http://java./xml/ns/javaee/web-app_2_5.xsd"> |
08 |
< welcome-file >index.jsp</ welcome-file > |
11 |
< param-name >contextConfigLocation</ param-name > |
13 |
classpath:server.xml classpath:client.xml |
19 |
org.springframework.web.context.ContextLoaderListener |
24 |
< servlet-name >CXFServlet</ servlet-name > |
26 |
org.apache.cxf.transport.servlet.CXFServlet |
31 |
< servlet-name >CXFServlet</ servlet-name > |
32 |
< url-pattern >/*</ url-pattern > |
客户端spring配置文件:client.xml
01 |
<? xml version = "1.0" encoding = "UTF-8" ?> |
02 |
< beans xmlns = "http://www./schema/beans" |
03 |
xmlns:xsi = "http://www./2001/XMLSchema-instance" xmlns:jaxws = "http://cxf./jaxws" |
05 |
http://www./schema/beans |
06 |
http://www./schema/beans/spring-beans.xsd |
07 |
http://cxf./jaxws http://cxf./schemas/jaxws.xsd"> |
10 |
< bean id = "logIn" class = "org.apache.cxf.interceptor.LoggingInInterceptor" /> |
11 |
< bean id = "logOut" class = "org.apache.cxf.interceptor.LoggingOutInterceptor" /> |
12 |
< bean id = "saajOut" class = "org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" /> |
13 |
<!-- <bean id="soapheaderOut" class="com.mms.client.writeSOAPHeaderInterceptor" /> --> |
14 |
< bean id = "wss4jOut" class = "org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" > |
17 |
< entry key = "action" value = "UsernameToken" /> |
18 |
< entry key = "passwordType" value = "PasswordText" /> |
19 |
< entry key = "user" value = "admin" /> |
20 |
< entry key = "passwordCallbackClass" value = "com.mms.client.ClientPasswordCallback" /> |
25 |
< jaxws:client id = "client" serviceClass = "com.mms.webservice.HelloWorld" address = "http://127.0.0.1:8080/CXFSecurity/HelloWorld" > |
26 |
< jaxws:inInterceptors > |
28 |
</ jaxws:inInterceptors > |
29 |
< jaxws:outInterceptors > |
31 |
< ref bean = "saajOut" /> |
32 |
<!--<ref bean="soapheaderOut" /> --> |
33 |
< ref bean = "wss4jOut" /> |
34 |
</ jaxws:outInterceptors > |
服务器spring配置文件:server.xml
01 |
< beans xmlns = "http://www./schema/beans" |
02 |
xmlns:xsi = "http://www./2001/XMLSchema-instance" xmlns:jaxws = "http://cxf./jaxws" |
04 |
http://www./schema/beans http://www./schema/beans/spring-beans.xsd |
05 |
http://cxf./jaxws http://cxf./schemas/jaxws.xsd"> |
06 |
<!-- jar包中自带的cxf文件夹下的*.xml文件 --> |
07 |
< import resource = "classpath:META-INF/cxf/cxf.xml" /> |
08 |
< import resource = "classpath:META-INF/cxf/cxf-extension-soap.xml" /> |
09 |
< import resource = "classpath:META-INF/cxf/cxf-servlet.xml" /> |
11 |
< bean id = "logIn" class = "org.apache.cxf.interceptor.LoggingInInterceptor" /> |
12 |
< bean id = "logOut" class = "org.apache.cxf.interceptor.LoggingOutInterceptor" /> |
13 |
< bean id = "saajIn" class = "org.apache.cxf.binding.soap.saaj.SAAJInInterceptor" /> |
14 |
<!-- <bean id="soapheaderIn" class="com.mms.webservice.test.readSOAPHeaderInterceptor" /> --> |
15 |
< bean id = "wss4jIn" class = "org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" > |
18 |
< entry key = "action" value = "UsernameToken" /> |
19 |
< entry key = "passwordType" value = "PasswordText" /> |
20 |
< entry key = "passwordCallbackClass" value = "com.mms.webservice.test.ServerPasswordCallback" /> |
24 |
< jaxws:endpoint id = "helloWorld" implementor = "com.mms.webservice.HelloWorldImpl" |
25 |
address = "/HelloWorld" > |
26 |
< jaxws:inInterceptors > |
29 |
<!--<ref bean="soapheaderIn" /> --> |
30 |
< ref bean = "wss4jIn" /> |
31 |
</ jaxws:inInterceptors > |
32 |
< jaxws:outInterceptors > |
34 |
</ jaxws:outInterceptors > |
测试Client.java
01 |
package com.mms.client; |
02 |
import org.springframework.context.ApplicationContext; |
03 |
import org.springframework.context.support.ClassPathXmlApplicationContext; |
04 |
import com.mms.webservice.HelloWorld; |
06 |
public final class Client { |
11 |
public static void main(String args[]) throws Exception { |
12 |
ApplicationContext context = new ClassPathXmlApplicationContext( |
13 |
new String[] { "client.xml" }); |
14 |
HelloWorld client = (HelloWorld) context.getBean( "client" ); |
15 |
String response = client.sayHi( "hello test!" ); |
16 |
System.out.println( "Response: " + response); |
|