码迷,mamicode.com
首页 > 其他好文 > 详细

其他系统与domino系统单点登录的实现方式

时间:2014-09-29 17:42:31      阅读:413      评论:0      收藏:0      [点我收藏+]

标签:domino   sso   ltpatoken   



其他系统与domino系统单点登录的实现方式

  • 【背景】

随着企业中业务不断增多,用户处理不同的业务则需要频繁的切换不同的系统进行操作,而用户则需要记住各个系统的用户名、密码,频繁的登录。如果各个系统间能够进行单点登录,无疑会大大减少用户重复输入密码的困扰。

由于domino系统相对比较封闭,其他系统想相对安全的单点domino系统并非易事。

也许有些人会说通过这样的方法,通过模拟用户登录的方式就可以实现:

Names.nsf?login&username=xxx&password=xxx

但是,这样实现显然不太安全,一个需要单独记录用户的明文密码(domino http密码是不可逆算法)。

 

我知道两种实现方式相对安全:DSAPI和模拟LTPAToken。本文介绍一种,通过dominoLTPAToken的生成方式实现单点登录的方法。

 

  • 【实现原理】

输入参数

1. 用户名;

2. 登录系统时间;

3. 登录到期时间;

4. Domino密钥

 

输出参数

         加密后的LTPAToken加密串

 

创建cookie

         document.cookie= "LtpaToken="+ token + ";expires=" + exp.toGMTString() +";path=/;domain=.xxx.com";

         token:加密token

         expirescookie到期时间

         domain:单点域名,与dominoSSO配置文档相同,格式:.xxx.com

 

  • 【参考代码】
  • java代码

     

    import java.io.PrintWriter;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    import lotus.domino.*;
    
    public class JavaAgent extends AgentBase {
    
        public void NotesMain() {
        	Session session = null;
        	AgentContext agentContext = null;
        	Document doc = null;
        	PrintWriter pw = null;
        	String token = "";
        	String sReturn = "false";
        	String sJson = "";
          try {
        	  pw = getAgentOutput();
              session = getSession();
              agentContext = session.getAgentContext();
              doc = agentContext.getDocumentContext();
              String sPara = doc.getItemValueString("query_string_decoded");
              // 单点用户名loginName
              String canonicalUser = sPara.substring(sPara.indexOf("sPara=")+6);
    
              // 单点起始时间
              Date tokenCreation = new Date(new Date().getTime() - 60000 * 10);
    		  String timeLimit="720";
    		  // 单点到期时间
    		  Date tokenExpires = new Date(tokenCreation.getTime() + Long.parseLong(timeLimit) * 60000);
    		  // domino SSO 密钥(domino SSO配置文档的LTPA_DominoSecret域值)
    		  String dominoSecret = "9BY2oinn1FmI42i3oNEnL3nNVPQ=";
    		  token = LtpaToken.generate(canonicalUser, tokenCreation, tokenExpires, dominoSecret).getLtpaToken();
    		  //System.out.println("token==ssobak==="+token);
    		  sReturn = "true";          
    		  DominoTokenParser tokenParser = new DominoTokenParser();		   
    		  System.out.println("用户名:"+tokenParser.parse(token,dominoSecret));
    		  
          } catch(Exception e) {
              e.printStackTrace();
           }finally{
        	   pw.println("Content-type: text/plain;charset=GB2312");
        	   sJson = "{\"oResult\":\""+sReturn+"\",\"token\":\""+token+"\"}";
        	   System.out.println("sJson="+sJson);
        	   pw.println(sJson);
        	   
        	   //回收domino对象
        	   fnRecycle(doc);
        	   fnRecycle(agentContext);
        	   fnRecycle(session);
        	   
        	   if(pw!=null){
    				pw.close();
    			}
           }
       }  
        
        public void fnRecycle(Base object){
        	if(object != null){
     		   try {
     			  object.recycle();
    			} catch (NotesException e) {
    				// TODO 自动生成 catch 块
    				e.printStackTrace();
    			}
     	   }
        }
    } 
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Properties;
    
     /** 
         * Lightweight Third Party Authentication. Generates and validates ltpa tokens used in Domino single sign on 
         * environments. Does not work with WebSphere SSO tokens. You need a properties file named LtpaToken.properties which 
         * holds two properties. 
         * 
         * <pre> 
         * ) domino.secret=The base64 encoded secret found in the field LTPA_DominoSecret in the SSO configuration document. 
         * ) cookie.domain=The domain you want generated cookies to be from. e.g. '.domain.com' (Note the leading dot) 
         *</pre> 
         * 
         * @author $Author: rkelly $ 
         * @version $Revision: 1.1 $ 
         * @created $Date: 2003/04/07 18:22:14 $ 
         */ 
    public final class LtpaToken { 
            private byte[] creation; 
            private Date creationDate; 
            private byte[] digest; 
            private byte[] expires; 
            private Date expiresDate; 
            private byte[] hash; 
            private byte[] header; 
            private String ltpaToken; 
            private Properties properties = null; 
            private byte[] rawToken; 
            private byte[] user; 
          
            
          
    
                /** 
             * Constructor for the LtpaToken object 
             * 
             * @param token 
             *            Description of the Parameter 
             */ 
            public LtpaToken(String token) { 
                init(); 
                ltpaToken = token; 
                rawToken = Base64.decode(token); 
                user = new byte[(rawToken.length) - 40]; 
                for (int i = 0; i < 4; i++) { 
                    header[i] = rawToken[i]; 
                } 
                for (int i = 4; i < 12; i++) { 
                    creation[i - 4] = rawToken[i]; 
                } 
                for (int i = 12; i < 20; i++) { 
                    expires[i - 12] = rawToken[i]; 
                } 
                for (int i = 20; i < (rawToken.length - 20); i++) { 
                    user[i - 20] = rawToken[i]; 
                } 
                for (int i = (rawToken.length - 20); i < rawToken.length; i++) { 
                    digest[i - (rawToken.length - 20)] = rawToken[i]; 
                } 
                creationDate = new Date(Long.parseLong(new String(creation), 16) * 1000); 
                expiresDate = new Date(Long.parseLong(new String(expires), 16) * 1000); 
            } 
    
            /** 
             * Constructor for the LtpaToken object 
             */ 
            private LtpaToken() { 
                init(); 
            } 
    
    
    
            /** 
             * Gets the creationDate attribute of the LtpaToken object 
             * 
             * @return The creationDate value 
             */ 
            public Date getCreationDate() { 
                return creationDate; 
            } 
    
            /** 
             * Gets the expiresDate attribute of the LtpaToken object 
             * 
             * @return The expiresDate value 
             */ 
            public Date getExpiresDate() { 
                return expiresDate; 
            } 
    
            /** 
             * Gets the user attribute of the LtpaToken object 
             * 
             * @return The user value 
             */ 
            public String getCanonicalUser() { 
                return new String(user); 
            } 
            
            public String getUser(String prefix, String suffix) {
            	String userName = new String(user);
            	if (prefix !=null && !prefix.equals("")) {
        			userName = userName.substring(userName.indexOf(prefix) + prefix.length());
        		}
        		if (suffix ==null || suffix.equals("")) {
        			suffix = "/";
        		} 
            	return userName.substring(0, userName.indexOf("/"));
            }
            
            public String getUser() { 
                return new String(user); 
            } 
    
    
            /** 
             * Validates the SHA-1 digest of the token with the Domino secret key. 
             * 
             * @return Returns true if valid. 
             */ 
            public  boolean isValid(LtpaTokenConfig config) { 
                boolean validDigest = false; 
                boolean validDateRange = false; 
                byte[] newDigest; 
                byte[] bytes = null; 
                Date now = new Date(); 
    
                MessageDigest md = getDigest(); 
    
                bytes = concatenate(bytes, header); 
    
                bytes = concatenate(bytes, creation); 
    
                bytes = concatenate(bytes, expires); 
    
                bytes = concatenate(bytes, user); 
    
                bytes = concatenate(bytes, Base64.decode(config.getDominoSecret())); 
    
                newDigest = md.digest(bytes); 
    
                validDigest = MessageDigest.isEqual(digest, newDigest); 
                
                validDateRange = now.after(creationDate) && now.before(expiresDate); 
    
                return validDigest & validDateRange; 
            } 
    
            /** 
             * String representation of LtpaToken object. 
             * 
             * @return Returns token String suitable for cookie value. 
             */ 
            public String toString() { 
                return ltpaToken; 
            } 
    
            /** 
             * Creates a new SHA-1 <code>MessageDigest</code> instance. 
             * 
             * @return The instance. 
             */ 
            private MessageDigest getDigest() { 
                try { 
                    return MessageDigest.getInstance("SHA-1");            
                } catch (NoSuchAlgorithmException nsae) { 
                    nsae.printStackTrace(); 
                } 
                return null; 
            } 
    
            /** 
             * Description of the Method 
             */ 
            private void init() { 
    
                creation = new byte[8]; 
                digest = new byte[20]; 
                expires = new byte[8]; 
                hash = new byte[20]; 
                header = new byte[4]; 
    
            } 
    
            /** 
             * Validates the SHA-1 digest of the token with the Domino secret key. 
             * 
             * @param ltpaToken 
             *            Description of the Parameter 
             * @return The valid value 
             */ 
            public static boolean isValid(String ltpaToken,LtpaTokenConfig config) { 
                LtpaToken ltpa = new LtpaToken(ltpaToken); 
                return ltpa.isValid(config); 
            } 
    
            /** 
             * Generates a new LtpaToken with given parameters. 
             * 
             * @param canonicalUser 
             *            User name in canonical form. e.g. 'CN=Robert Kelly/OU=MIS/O=EBIMED'. 
             * @param tokenCreation 
             *            Token creation date. 
             * @param tokenExpires 
             *            Token expiration date. 
             * @return The generated token. 
             */ 
            public static LtpaToken generate(String canonicalUser, Date tokenCreation, Date tokenExpires,String  secret) { 
                LtpaToken ltpa = new LtpaToken(); 
                System.out.println("Generating token for " + canonicalUser); 
                Calendar calendar = Calendar.getInstance(); 
                MessageDigest md = ltpa.getDigest(); 
                ltpa.header = new byte[] { 0, 1, 2, 3 }; 
                byte[] token = null; 
                calendar.setTime(tokenCreation); 
                ltpa.creation = Long.toHexString(calendar.getTimeInMillis() / 1000).toUpperCase().getBytes(); 
                calendar.setTime(tokenExpires); 
                ltpa.expires = Long.toHexString(calendar.getTimeInMillis() / 1000).toUpperCase().getBytes();  
                //try {
    			//	canonicalUser = new String(canonicalUser.getBytes(), "GB2312");
    			//} catch (UnsupportedEncodingException e) {
    				// TODO 自动生成 catch 块
    			//	e.printStackTrace();
    			//}
                ltpa.user = canonicalUser.getBytes(); 
                //ltpa.user = canonicalUser.getBytes(Charset.forName("GB18030")); 
    
                token = concatenate(token, ltpa.header); 
                token = concatenate(token, ltpa.creation); 
                token = concatenate(token, ltpa.expires); 
                token = concatenate(token, ltpa.user); 
                md.update(token); 
                ltpa.digest = md.digest(Base64.decode(secret)); 
                token = concatenate(token, ltpa.digest); 
    
                return new LtpaToken(new String(Base64.encodeBytes(token,Base64.DONT_BREAK_LINES)));            
            } 
    
            /** 
             * Helper method to concatenate a byte array. 
             * 
             * @param a 
             *            Byte array a. 
             * @param b 
             *            Byte array b. 
             * @return a + b. 
             */ 
            private static byte[] concatenate(byte[] a, byte[] b) { 
                if (a == null) { 
                    return b; 
                } else { 
                    byte[] bytes = new byte[a.length + b.length]; 
    
                    System.arraycopy(a, 0, bytes, 0, a.length); 
                    System.arraycopy(b, 0, bytes, a.length, b.length); 
                    return bytes; 
                } 
            } 
    
            public String getLtpaToken() { 
                return ltpaToken; 
            } 
    
            public void setLtpaToken(String ltpaToken) { 
                this.ltpaToken = ltpaToken; 
            } 
        }


  • js代码

     

    function fnSSO(){
    	if(document.getElementById("username").value==""){
    		alert("请输入登录名!");
    		document.getElementById("username").focus();
    		return false;
    	}
    	var objHTTP= new ActiveXObject("Microsoft.XMLHTTP");
    	var sDbPath = document.getElementById("DbFilePath").value;
    	var sPara = document.getElementById("username").value;
    	var vurl = "/"+sDbPath+"/"+"ajaxSSO" + "?openagent&sPara=" + sPara;
    	objHTTP.open("GET", vurl, false, "", "");
    	objHTTP.setRequestHeader("If-Modified-Since","0");
    	objHTTP.send(false);
    	var getOptions = objHTTP.responseText;
    	getOptions = getOptions.replace(/\n/ig,"");
    	var oOptions = eval("(" + getOptions + ")");
    	var sReturn = "";
    	if(oOptions && oOptions.oResult=="true"){
    		var Days = 30; 
    		var exp = new Date(); 
    		exp.setTime(exp.getTime() + Days*24*60*60*1000);
    		var token = oOptions.token;
    		if(token!=""){
    			// 创建单点cookie
    			document.cookie = "LtpaToken="+ token + ";expires=" + exp.toGMTString() + ";path=/;domain=.xxx.com";
    		}
    		sReturn = sPara + ":单点登录成功!"
    	}else{
    		sReturn = sPara + ":单点失败!"
    	}
    	
    	document.getElementById("ssoinfo").innerHTML = "<font color='red'>" + sReturn + "</font>";
    	// 页面跳转
    	location.href = "http://xxx.com/xxx.nsf/xxx?openform";
    }


  • 【实现效果】 

bubuko.com,布布扣

其他系统与domino系统单点登录的实现方式

标签:domino   sso   ltpatoken   

原文地址:http://blog.csdn.net/gavid0124/article/details/39669521

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!