2012-07-06 88 views
2

在这里急需帮助,保护简单的Apache CXF Web服务。尝试使用Spring Security并不在我的位置,所以我需要找到一个不同的策略。这是对我们的一些客户实施的传统Java服务实施授权。使用INI通过Apache Shiro保护Apache CXF Webservice

这个简单的Apache CXF Web服务是使用Maven的cxf-jaxws-javafirst原型创建的。 它生成了一个web.xml和beans.xml文件和示例代码。

web.xml中:

<?xml version="1.0" encoding="ISO-8859-1"?> 

<!DOCTYPE web-app 
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
    "http://java.sun.com/dtd/web-app_2_3.dtd"> 


<web-app> 
    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>WEB-INF/beans.xml</param-value> 
    </context-param> 
    <context-param> 
    <param-name>shiroConfigLocations</param-name> 
     <param-value>WEB-INF/shiro.ini</param-value> 
     </context-param> 

    <filter> 
     <filter-name>ShiroFilter</filter-name> 
     <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>  
    </filter> 

    <filter-mapping> 
     <filter-name>ShiroFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <listener>  
     <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 
    </listener> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener> 


    <servlet> 
     <servlet-name>CXFServlet</servlet-name> 
     <display-name>CXF Servlet</display-name> 
     <servlet-class> 
      org.apache.cxf.transport.servlet.CXFServlet 
     </servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>CXFServlet</servlet-name> 
     <url-pattern>/*</url-pattern> 
    </servlet-mapping> 
</web-app> 

和我Shiro.ini文件看起来像这样:

# ======================= 
# Shiro INI configuration 
# ======================= 

[main] 
authc = org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter 

[users] 
o = o, OPERATOR 
a = a, ADMIN 
s = s, SUPERVISOR 

[roles] 
SUPERVISOR = * 
ADMIN = sayHiAdmin 
OPERATOR = deleteAccounts 
除了beans.xml文件保留在默认状态,具体如下我已经修改了这些实体

我简单的web服务的代码如下:

import javax.jws.WebService; 

import org.apache.shiro.SecurityUtils; 
import org.apache.shiro.authz.Permission; 
import org.apache.shiro.authz.UnauthorizedException; 
import org.apache.shiro.subject.Subject; 

@WebService(endpointInterface = "org.myCo.com.CxfShiroSecuredService.HelloWorld") 
public class HelloWorldImpl implements HelloWorld { 

    public String sayHi(String text) {    

     if (isAuthorized("sayHi")) { 
      return "Successfully said hi " + text; 
     }    

     if (hasRole("OPERATOR")){ 
      return "User is OPERATOR"; 
     } 
     if (hasRole("ADMIN")){ 
      return "User is OPERATOR"; 
     } 
     throw new UnauthorizedException("Logged user does not have OPERATOR's permission");        
    }  

    public String sayHiAdmin(String text) {   

     if (isAuthorized("sayHiAdmin")) { 
      return "Successfully said hi Admin " + text; 
     }    

     throw new UnauthorizedException("Logged user does not have ADMIN permission"); 
    } 

    public String deleteAccounts(String text) {    

     if (isAuthorized("deleteAccounts")) { 
      return "Successfully deleted accounts " + text; 
     }    

     throw new UnauthorizedException("Logged user does not have SUPERVISOR permission"); 
    } 

    private Boolean isAuthorized(String operation){ 
     Subject currentUser = SecurityUtils.getSubject();  
     return currentUser.isPermitted(operation); //currentUser.isAuthenticated(); // && currentUser.isPermitted(operation);  
    } 

    private Boolean hasRole(String role){ 
     Subject currentUser = SecurityUtils.getSubject();  
     return currentUser.hasRole(role);  
    } 
} 

我有一个调用webservice的像这样之前通过在SOAP头认证信息的C#测试客户端:

private void OnButtonClick(object sender, RoutedEventArgs e) 
     { 
      var client = new HelloWorldClient(); 
      var response = ""; 

      using (new OperationContextScope(client.InnerChannel)) 
      { 
       var httpRequestProperty = new HttpRequestMessageProperty(); 
       httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + 
       Convert.ToBase64String(Encoding.ASCII.GetBytes(UserName.Text + ":" + Password.Text)); 
       OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty; 

       try 
       { 
        response = client.sayHi("hi " + UserName.Text); 
       } 
       catch (TimeoutException tex) 
       { 
        response = tex.Message; 
       } 
       catch (CommunicationException cex) 
       { 
        response = cex.Message; 
       } 
      } 

      TextBox.Text = response; 

     } 

我已经使用该调用方法之前,需要基本身份认证 其他Web服务同样的策略与成功,但调用这项服务似乎没有认出我的凭据。对于每个调用的方法调用,无论用户名/密码组合如何,我都会抛出UnAuthorizedException异常。有人能给我一些亮光吗?

在此先感谢。

回答

2

您需要shiro.ini文件中的[url]部分。类似这样的:

[urls] 
/** = authc 

查阅文档了解更多详情here

+0

这是缺少的元素。这是Spring Security的一个很好的选择。配置和开箱即用非常容易。与Spring相比,我可以在所有这些时间内完成所有这些工作不到4个小时,而现在我在将近一周之内还没有弄清楚。感谢我以积极的方式结束本周。 – 2012-07-06 21:41:11