`

SpringSide实现XFire Webservice认证

阅读更多

XFire官方网站提供的基于Webservice认证的例子有问题,在新版本的XFire1.1.2中编译不通过,不过这也是小Case,我后来折腾了一下,为SpringSide提供了一个简单的Webservice认证功能。
XFire 跟Spring的天然融合,让我们可以少努力10年就能简单地在Spring中使用Webservice的强大魅力,我从AXIS专向XFire有一些冲动,也吃了不少亏,但受REST一族的强力吹捧,感觉还是值得尝试的,因此,在公司的系统中也把Axis彻底换了XFire。

回到SpringSide,我大概介绍一下如何配置一个真正实用的XFire验证服务。
SpringSide中的XFire配置文件放在:
SpringSide-bookstore\src\org\springside\bookstore\plugins\webservice\applicationContext-webservice-server.xml
我们在里面定义各个Webservice,该文件其实对应于XFire官方的XFire-Servlet.xml
看看下面的BookService,这是一个典型的Webservice服务,红色的inHandlers是我挂上去的。它的意思是所有访问BookService的请求都会被先送到authenticationHandler去处理,我们的验证逻辑可以在里面进行。
    <!--Web Service 在SpringMVC中的URL 路径映射-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>/BookService=bookWebService</value>
        </property>
        <property name="inHandlers">
            <ref bean="authenticationHandler"/>
        </property>
    </bean>

我们接着看看authenticationHandler的代码:
我们在SpringSide中通过header方式向服务器提供验证信息(另外一种更简单的方式是创建一个Login的webservice服务,然后在XFire Session中建立Token信息)。

package org.springside.bookstore.plugins.webservice.authentication;

import
 org.apache.log4j.Logger;
import
 org.codehaus.xfire.MessageContext;
import
 org.codehaus.xfire.exchange.InMessage;
import
 org.codehaus.xfire.fault.XFireFault;
import
 org.codehaus.xfire.handler.AbstractHandler;
import
 org.jdom.Element;
import
 org.jdom.Namespace;


/**

 * XFire的回调的Handler,在XFire配置文件中配置
 * Server端的认证模块,回调处理模块
 * 
 * ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用
 * 
 * 
@author  david.turing
 * @blog  openssl.blogjava.net
 *
 
*/

public class AuthenticationHandler extends AbstractHandler {
    
private static final Logger log = Logger.getLogger(AuthenticationHandler.class
);
    
    
public void invoke(MessageContext context) throws
 Exception {
        
        log.info(
"#AuthenticationHandler is invoked"
);
        InMessage message
=
context.getInMessage();
        
        
final Namespace TOKEN_NS = Namespace.getNamespace("SpringSide","http://service.webservice.plugins.bookstore.springside.org"
);  
        
        
if(message.getHeader()==null
)
        {
            
throw new XFireFault("GetRelation Service Should be Authenticated"
,
                    XFireFault.SENDER);
        }
        
        Element token 
= message.getHeader().getChild("AuthenticationToken"
, TOKEN_NS);
        
if (token == null
)
        {
            
throw new XFireFault("Request must include authentication token."
,
                                 XFireFault.SENDER);
        }

        String username 
= token.getChild("Username"
, TOKEN_NS).getValue();
        String password 
= token.getChild("Password"
, TOKEN_NS).getValue();

        System.out.println(
"username="+
username);        
        System.out.println(
"password="+
password);
        
        
if(username==null||password==null
)
            
throw new XFireFault("Supplied Username and Password Please"
,
                    XFireFault.SENDER);
        
        
/**

         * 检查用户名密码是否正确
         
*/
        PasswordAuthenticationManager pamanager
=new PasswordAuthenticationManager();
        
if(!
pamanager.authenticate(username,password))
            
throw new XFireFault("Authentication Fail! Check username/password"
,
                    XFireFault.SENDER);
 
        
    }
}

注意,XFireFault异常是往客户端抛的,Webservice Client应该学会catch XFireFault.

服务器端就是这么简单,看看客户端的TestCase

package org.springside.bookstore.plugins.webservice.service;

import
 java.lang.reflect.Proxy;
import
 java.net.MalformedURLException;
import
 java.util.List;

import
 org.codehaus.xfire.client.Client;
import
 org.codehaus.xfire.client.XFireProxy;
import
 org.codehaus.xfire.client.XFireProxyFactory;
import
 org.codehaus.xfire.service.Service;
import
 org.codehaus.xfire.service.binding.ObjectServiceFactory;
import
 org.springside.bookstore.commons.domain.Book;
import
 org.springside.bookstore.plugins.webservice.authentication.ClientAuthHandler;

import
 junit.framework.TestCase;

public class BookServiceWithAuthenticationTestCase extends
 TestCase {

    
protected void setUp() throws
 Exception {
        
super
.setUp();
    }

    
protected void tearDown() throws
 Exception {
        
super
.tearDown();
    }
    
    
public void getBookFromWebservice() throws
 Exception{
    
          Service serviceModel 
= new
 ObjectServiceFactory()
                .create(BookService.
class
);
        BookService service 
= null
;
        
        
try
 {
            service
=(BookService) new
 XFireProxyFactory().create(
                    serviceModel,
                    
"http://localhost:8080/springside/service/BookService"
);
        } 
catch
 (MalformedURLException e) {
            e.printStackTrace();
        }
        
        Client client 
=
 ((XFireProxy) Proxy.getInvocationHandler(service)).getClient();
        
//挂上ClientAuthHandler,提供认证

        client.addOutHandler(new ClientAuthHandler());
        List list 
= service.findBooksByCategory(null
);
        assertNotNull(list);
        
for(int i=0;i<list.size();i++
)
            System.out.println(((Book)list.get(i)).getName());
    }

}


你应该看到上面的client.addOutHandler(new ClientAuthHandler());
没错,它跟服务器端的AuthenticationHandler是一对,一起使用的!
也就是,每个被送往WebService服务的请求都被ClientAuthHandler处理过了。
看看ClientAuthHandler做了些什么:

package org.springside.bookstore.plugins.webservice.authentication;

import
 org.apache.log4j.Logger;
import
 org.codehaus.xfire.MessageContext;
import
 org.codehaus.xfire.handler.AbstractHandler;
import
 org.jdom.Element;
import
 org.jdom.Namespace;

/**

 * 客户端端的认证模块,回调处理模块
 * 每个需要认证的WebService方法都可以挂这个Handler
 * 
 * 仅用于Demo,从解耦和易用性出发,
 * 没有跟Acegi结合,你可以任意扩展
 * 默认用户名/密码是admin/admin
 * 
 * ClientAuthHandler跟AuthenticationHandler要一起用,或者都不用
 * 
 * 
@author  david.turing
 *
 * @blog openssl.blogjava.net
 
*/
    
public class ClientAuthHandler extends
 AbstractHandler {
        
private static final Logger log = Logger.getLogger(ClientAuthHandler.class
);
        
        
//客户端自己配置用户名密码或者更安全的KeyStore方式

        private String username = "admin";
        
private String password = "admin"
;
        
        
public
 ClientAuthHandler() {
        }
        
        
public
 ClientAuthHandler(String username,String password) {
            
this.username =
 username;
            
this.password =
 password;
        }
        
        
public void
 setUsername(String username) {
            
this.username =
 username;
        }
        
        
public void
 setPassword(String password) {
            
this.password =
 password;
        }
        
        
public void invoke(MessageContext context) throws
 Exception {
                        
            
/**
*****************************************
             * Soap Header方式
             * 从Soap Header中获取用户名密码
             ******************************************
*/

            
final Namespace ns = Namespace.getNamespace("SpringSide","http://service.webservice.plugins.bookstore.springside.org");  
            Element el 
= new Element("header"
,ns);

            Element auth 
= new Element("AuthenticationToken"
, ns);
            Element username_el 
= new Element("Username"
,ns);
            username_el.addContent(username);
            Element password_el 
= new Element("Password"
,ns);
            password_el.addContent(password);
            auth.addContent(username_el);
            auth.addContent(password_el);
            el.addContent(auth);            
            context.getCurrentMessage().setHeader(el);            
            log.info(
"ClientAuthHandler done!"
);
        }
    }


不就是往header里面注入username,password!

在SpringSide中,所有的Spring配置文件都被小白分散到各个Module中去了,Wuyu原先是在Plugin中提供Webservice功能,因此,我仍然在Plugin中创建XFire接口。
SpringSide的Spring配置文件放在:
SpringSide-bookstore\webapp\WEB-INF\springmvc-servlet.xml
该文件定义了Plugin的xml:
AuthenticationHandler这个Bean需要先定义在Plugins-servlet.xml中,其它很简单,大家去Try一下就知道了。

分享到:
评论

相关推荐

    WebService资料文件下载

    而"在SpringSide实现XFire Webservice认证.pdf"可能涉及了如何在Spring框架中集成XFire,实现WebService的安全认证。 5. **安全与WSSecurity**:"XFire+WSSecurity.pdf"可能涵盖了WebService的安全性,特别是...

    springside-3.2.2源码

    3. Spring Security:负责权限控制,配置 SecurityFilterChain 来拦截请求,实现用户认证和授权。 三、代码组织与设计模式 1. 单元测试:SpringSide 强调测试驱动开发,每个模块都有相应的单元测试,使用了 JUnit ...

    SpringSide4 参考手册

    SpringSide4参考手册是一份详尽的...无论是前端技术如Ajax、JQuery,还是后端技术如SpringMVC、数据持久化、安全认证、缓存管理等,手册都有详细的描述和使用案例,这使得它成为SpringSide开发者不可或缺的参考资料。

    Springside-core-4.1.0/Springside-core-4.1.0

    2. **安全框架集成**:集成了Spring Security,提供了用户认证、授权等功能,保障了应用的安全性。 3. **数据访问层**:支持多种ORM框架,如Hibernate和MyBatis,提供统一的DAO接口,降低了数据访问层的复杂性。 4...

    springside开发全面讲解

    7. **安全控制**:springside内置了Spring Security模块,用于实现权限控制、认证和授权,保障了系统的安全性。 8. **持续集成**:与Jenkins、Git等工具集成,springside支持持续集成和版本控制,方便团队协作。 9...

    springside3.0.zip

    4. **Quartz调度器**:SpringSide 3.0 包含了Quartz库,用于实现任务调度功能。开发者可以通过Quartz创建、安排和执行定时任务,提升应用的自动化水平。 5. **Web MVC模式**:Spring MVC是Spring框架的一部分,提供...

    springside框架

    通过集成Spring Security或Apache Shiro等安全框架,SpringSide可以实现细粒度的权限控制,确保系统在不同用户、不同场景下的安全性。 五、SpringSide的项目结构与实践 SpringSide项目通常采用模块化设计,包括...

    springside

    在实际应用中,SpringSide可以应用于各种场景,如开发企业级的Web应用、构建微服务、实现数据访问层的自动化等。通过熟练掌握SpringSide,开发者不仅可以提高开发效率,还能确保项目具有良好的可维护性和扩展性。 ...

    springside的jar包

    6. **安全控制**:Springside提供了基于Spring Security的安全控制模块,可以快速实现用户认证与授权功能,增强了应用的安全性。 7. **日志管理**:集成了Logback作为日志系统,提供了灵活的日志级别控制和输出格式...

    springside-core-4.2.2.GA(含关联的test.jar)

    pom.xml配置 ...mvn install:install-file -DgroupId=org.springside -DartifactId=springside-core -Dversion=4.2.2.GA -Dfile=./springside-core-4.2.2.GA.jar -Dpackaging=jar -DgeneratePom=true

    有springside4.2.3-GA.jar 包

    《深入解析springside4.2.3-GA.jar:Java开发者的宝藏库》 在Java开发领域,SpringSide框架以其高效、灵活和强大的特性深受开发者喜爱。本文将围绕springside4.2.3-GA.jar这个核心组件,探讨其在Java应用中的重要...

    SpringSide3.3.4安装部署

    我们还可以使用 Spring Security 来实现身份验证和授权。 SpringSide3.3.4 安装部署是一个复杂的过程,它需要我们具备一定的 Java 和 Maven 知识。通过本文,我们了解了 SpringSide3.3.4 安装部署的步骤和相关知识...

    springside.jar

    从项目构建、测试到功能实现,springside.jar都为Java开发者提供了高效、规范的解决方案。在实际开发中,合理利用springside.jar,不仅能提升开发效率,还能保证代码质量和项目稳定性。因此,理解和掌握springside....

    springside4(showcase)

    SpringSide 4的showcase还会展示如何整合其他Spring模块,比如Spring Security进行权限管理,Spring Data进行数据访问,Spring AOP实现切面编程,以及Spring Test进行单元测试和集成测试。所有这些都将帮助开发者...

    springside-4.0.0.GA.zip

    SpringSide将Spring的核心功能如依赖注入、AOP(面向切面编程)、事务管理、数据访问等进行了封装和优化,使得开发者可以更加专注于业务逻辑,而非底层实现细节。 在“springside-4.0.0.GA”压缩包中,我们可以期待...

    springside3.3.4 使用方法

    - 它定义了一套MVC模式的标准实现,使得视图层与模型层分离,易于维护和扩展。 3. **Hibernate**: - Hibernate是持久化层的首选框架,用于对象关系映射(ORM)。 - 它简化了数据库操作,提供了高效的缓存机制,...

    springside3源码及jar

    3. **示例代码**:jar包中的源码是学习和借鉴的好材料,开发者可以通过阅读源码来了解springside3的实现原理,以及如何在自己的项目中应用。 总结,springside3是一个优秀的Java开发工具,它不仅提供了便捷的开发...

    springside3.3完整版

    这三个框架的整合能够实现高效的MVC开发,Struts2处理请求和展示视图,Hibernate负责持久化操作,Spring则协调整个应用的运行。 6. **代码规范与最佳实践** SpringSide一直强调代码的规范性和最佳实践,3.3版本也...

    SpringSide3-core-3.3.4

    3. **安全组件**:可能包含Spring Security的集成,提供用户认证和授权功能,确保应用的安全性。 4. **任务调度**:可能集成了Quartz或其他任务调度库,方便开发者进行定时任务的设定和管理。 5. **自定义组件**:...

    SpringSide安全框架demo实例

    在SpringSide安全框架中,认证通常通过实现UserDetailsService接口来完成。你可以自定义一个服务类,重写loadUserByUsername方法,将用户名与数据库中的用户信息进行匹配。这样,当用户尝试登录时,Spring Security...

Global site tag (gtag.js) - Google Analytics