2012-07-06 99 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