CAS

需求描述1:大家知道J2EE应用程序都可以用类型以下形式进行保护: 

Xml代码   收藏代码
  1. <login-config>  
  2.      <auth-method>FORM</auth-method>  
  3.      <form-login-config>  
  4.      <form-login-page>/login.jsp</form-login-page>  
  5.      <form-error-page>/failure.jsp</form-error-page>  
  6.      </form-login-config>  
  7.      <realm-name>Security Realm</realm-name>  
  8.  </login-config>  
  9.  <security-constraint>   
  10.     <display-name>Tomcat security constraint</display-name>   
  11.     <web-resource-collection>   
  12.          <web-resource-name>Protected Resources</web-resource-name>   
  13.          <url-pattern>/security/*</url-pattern>   
  14.    </web-resource-collection>   
  15.   
  16.    <auth-constraint>   
  17.       <role-name>manager</role-name>   
  18.    </auth-constraint>   
  19.  </security-constraint>   
  20.  <security-role>  
  21.      <role-name>manager</role-name>  
  22.  </security-role>  

而使用CAS实现SSO之后,我们又不想容器保护去掉,该怎么办才能真正把这个CAS验证过的用户和角色传给Tomcat容器,而不至于重新登录,或者出现403错误呢? 
需求描述2: 在有EJB资源的时候,我们通常都会用JAAS来实现保护EJB资源,以限制EJB资源的访问。在调用EJB的时候,需要输入用户名和密码并且此用户具有相应的角色才能调用EJB。而在实现SSO之后,如果真正实现与EJB容器进行SSO呢? 


下面基于Tomcat容器实现需求1.
 
1. Tomcat窗口提供了一个叫Valve的接口,还提供一个基本实现ValveBase,我们解决方案就是基于实现一个自己的Valve, 在Valve里把经过CAS验证的用户传给Tomcat。以下就是自定义的Valve: 
Java代码   收藏代码
  1. package edu.extcas.valve;  
  2.   
  3. import java.io.*;  
  4. import java.security.Principal;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7.   
  8. import javax.servlet.*;  
  9. import javax.servlet.http.*;  
  10.   
  11. import org.apache.catalina.Container;  
  12. import org.apache.catalina.connector.Request;  
  13. import org.apache.catalina.connector.Response;  
  14. import org.apache.catalina.realm.GenericPrincipal;  
  15. import org.apache.catalina.valves.ValveBase;  
  16.   
  17. //import com.ttg.customagent.jboss.SimplePrincipal;  
  18.   
  19. public class ExtCASValve extends ValveBase {  
  20.     public final static String CAS_FILTER_USER = "edu.yale.its.tp.cas.client.filter.user";  
  21.   
  22.     public void setContainer(Container container) {  
  23.         super.setContainer(container);  
  24.     }  
  25.   
  26.     public void invoke(Request request, Response response) throws IOException,  
  27.             ServletException {  
  28.         HttpSession session = ((HttpServletRequest) request).getSession();  
  29.   
  30.         if (session != null) {  
  31.             String username = (String) session.getAttribute(CAS_FILTER_USER);  
  32.             if (null != username) {  
  33.                 List roleList = getRolesFromUserStore(username);  
  34.                 Principal principal = new GenericPrincipal(request.getContext()  
  35.                         .getRealm(), username, "", roleList);  
  36.                 request.setUserPrincipal(principal);  
  37.             }  
  38.   
  39.             //SecurityAssociation类是在登录EJB的时候使用的。  
  40.             //SecurityAssociation.setPrincipal(new SimplePrincipal(username.trim()));  
  41.             //SecurityAssociation.setCredential("password".trim().toCharArray());  
  42.               
  43.             getNext().invoke(request, response);  
  44.             return;  
  45.         } else {  
  46.             getNext().invoke(request, response);  
  47.             return;  
  48.         }  
  49.     }  
  50.   
  51.   //此方法是为在用户存储里取到相应的角色。自已根据实际情况实现  
  52.     private List getRolesFromUserStore(String username) {  
  53.         List roleList = new ArrayList();  
  54.         roleList.add("admin");  
  55.         roleList.add("manager");  
  56.         return roleList;  
  57.     }  
  58.   
  59. }  

2. 实现好自己的Valve,在server.xml里配置一下。然后就可以测试了。 


下面讲实现需求2实现的思路: 
1. 如果是EJB容器是JBoss,而Web容器是Tomcat, 也可以在Valve里用SecurityAssociation类(或者其他的方法)把CAS验证过的用户传到EJB容器里。这里同时需要传递密码。 
2. 要实现一个LoginModule, 类似以下代码: 
Java代码   收藏代码
  1. package edu.extcas.loginmodule;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import java.util.Set;  
  9. import java.security.Principal;  
  10. import java.security.cert.X509Certificate;  
  11. import javax.security.auth.Subject;  
  12. import javax.security.auth.callback.Callback;  
  13. import javax.security.auth.callback.CallbackHandler;  
  14. import javax.security.auth.callback.NameCallback;  
  15. import javax.security.auth.callback.PasswordCallback;  
  16. import javax.security.auth.callback.UnsupportedCallbackException;  
  17. import javax.security.auth.login.LoginException;  
  18. import javax.security.auth.spi.LoginModule;  
  19. import org.apache.catalina.realm.GenericPrincipal;  
  20.   
  21. public class ExtCasLoginModule  implements LoginModule {  
  22.   
  23.     private CallbackHandler callbackHandler;  
  24.   
  25.     private Principal unauthenticatedIdentity;  
  26.   
  27.     private String userName = null;  
  28.   
  29.     private String password = null;  
  30.       
  31.     protected Subject subject;  
  32.       
  33.     protected boolean loginOk;  
  34.   
  35.     protected Principal identity;  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值