EIA单点登录
典型配置举例
资料版本:5W106-20221228
产品版本:AD-Campus EIA (E6204)
Copyright © 2022 新华三技术有限公司 版权所有,保留一切权利。
非经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档内容的部分或全部,并不得以任何形式传播。
除新华三技术有限公司的商标外,本手册中出现的其它公司的商标、产品标识及商品名称,由各自权利人拥有。
本文档中的信息可能变动,恕不另行通知。
目 录
EIA单点登录是将入网认证和应用认证进行整合的一种认证方式。即终端用户进行一次认证后,既可以顺利接入网络,又能访问各种Web应用系统。
目前EIA单点登录具体应用包括:
· Web应用系统 > Portal:终端用户不是通过Portal服务器上的登录页面做认证,而是经由第三方应用代用户将认证信息发到Portal服务器做认证,不支持安全检查。
· Web应用系统 > BYOD:终端用户不是通过BYOD服务器上的登录页面做认证,而是经由第三方应用代用户将认证信息发到BYOD服务器做认证,不支持安全检查。
用户需要认证后接入网络并访问各种Web应用系统的场合。
第三方Web应用系统已经配置完成,请参见4 附录:公共样例代码。
某公司计划启用Portal认证,用户接入网络时需要进行身份验证,具体的组网如图2所示。本文档中的EIA和Portal服务器为同一台服务器。
· EIA服务器IP地址为192.168.7.220。查看方式如下:
· 在集群部署环境中,会涉及EIA服务器IP地址使用北向业务虚IP还是所在实际节点IP的问题,该地址请务必填写为北向业务虚IP。
· 下述步骤为查看EIA服务器IP地址的通用步骤,涉及到的IP地址与本文档无关,以查看EIA服务器IP地址“10.114.117.164”为例进行介绍。
a. 打开浏览器输入https://ip_address:8443/matrix/ui,打开Matrix页面。其中,ip_address为北向业务虚IP或节点IP。
b. 选择“部署”页签,单击“集群”菜单项,切换至“集群参数”页签,进入集群参数页面。
c. 该页面中的北向业务虚IP即为EIA服务器的IP地址,如图1所示。
图1 查看EIA服务器IP地址
注:本案例中各部分使用的版本如下:
· EIA版本:AD-Campus EIA (E6204)
· 接入设备:H3C S5820V2-54QS-GE
使用单点登录功能必须先对EIA服务器进行配置。
配置EIA服务器时,需要配置以下功能:
· 接入设备
· 接入策略
· 接入服务
· 接入用户
增加接入设备是为了建立EIA服务器和接入设备之间的联动关系。增加接入设备的方法如下:
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 接入服务”菜单项,进入接入服务页面。切换至“接入设备 > 接入设备配置”页签,进入接入设备配置页面,如图3所示。
(2) 单击<增加>按钮,进入增加接入设备页面,如图4所示。
(3) 单击“设备列表”区域中的<增加IPv4设备>按钮,弹出增加接入设备窗口,如图5所示。输入接入设备的IP地址,单击<确定>按钮,返回增加接入设备页面。其中,接入设备的IP地址必须满足以下要求:
¡ 如果在接入设备上配置radius scheme时配置了nas ip命令,则EIA中接入设备的IP地址必须与nas ip的配置保持一致。
¡ 如果未配置nas ip命令,则EIA中接入设备的IP地址必须是设备连接EIA服务器的接口IP地址(或接口所在VLAN的虚接口IP地址)。
图5 手工增加接入设备
(4) 配置公共参数。公共参数的配置要求如下:
¡ 认证端口:EIA监听RADIUS认证报文的端口。此处的配置必须与接入设备命令行配置的认证端口保持一致。EIA和接入设备一般都会采用默认端口1812。
¡ 计费端口:EIA监听RADIUS计费报文的端口。此处的配置必须与接入设备命令行配置的计费端口保持一致。EIA和接入设备一般都会采用默认端口1813。
目前仅支持将EIA同时作为认证和计费服务器,即不支持将EIA作为认证服务器,而其他服务器作为计费服务器的场景。
¡ 共享密钥/确认共享密钥:输入两次相同的共享密钥。接入设备与EIA配合进行认证时,使用该密钥互相验证对方的合法性。此处的配置必须与接入设备命令行配置的共享密钥保持一致。如果在[自动化>用户业务>业务参数>接入参数>系统配置>系统参数配置]中的“密钥显示方式”设置为明文时,只需输入一次共享密钥即可。
¡ 其他参数保持默认。
本例以共享密钥\确认共享密钥“movie”为例进行介绍,其他保持默认即可,如图6所示。
(5) 单击<确定>按钮,增加接入设备完毕,可在接入设备列表中查看新增的接入设备,如图7所示。
配置一个不进行任何接入控制的接入策略。增加接入策略的方法如下:
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 接入服务”菜单项,进入接入服务页面。切换至“接入策略 > 接入策略”页签,进入接入策略页面,如图8所示。
(2) 单击<增加>按钮,进入增加接入策略页面,如图9所示。由于不需要任何接入控制,所以只需输入接入策略名,其他参数保持默认即可。
授权下发需要设备支持对应属性,认证绑定需要设备在RADIUS属性中上传对应信息。本例不对设备进行任何下发,因此保持默认。
(3) 单击<确定>按钮,接入策略增加完毕。返回接入策略管理页面,可在接入策略列表中查看新增的接入策略,如图10所示。
接入服务是对用户进行认证授权的各种策略的集合。本例不对用户进行任何接入控制,因此只需增加一个简单的接入服务即可。增加接入服务的方法如下:
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 接入服务”菜单项,进入接入服务页面,如图11所示。
(2) 单击<增加>按钮,进入增加接入服务页面,配置服务名、服务后缀、缺省接入策略,其他参数保持默认,如图12所示。
配置服务的各个参数:
¡ 服务名:输入服务名称,在EIA中必须唯一。
¡ 服务后缀:服务后缀、认证连接的用户名、设备的Domain和设备Radius scheme中的命令这四个要素密切相关,具体的搭配关系请参见表1。
¡ 缺省接入策略:选择之前新增的接入策略。
¡ 安全组:选择的安全组。
¡ 安全子组:选择的安全子组。
¡ 缺省私有属性下发策略:不受接入位置分组限制的用户上网时,EIA会根据本参数指定的策略将私有属性下发到此用户连接的接入设备上。
¡ 缺省单帐号最大绑定终端数:接入用户的接入场景与服务中的接入场景均不匹配时,用户受到缺省单帐号最大绑定终端数的控制。该参数只有在部署了EIP组件后才会显示。
- 匹配的接入场景:EIA检查该场景中用户已经绑定的终端数量是否已达到数量限制,如果已达到数量限制,则拒绝用户认证;
- 所有服务中包含的场景:检查用户申请的所有服务中(包括服务中的所有场景)已绑定的终端数量,如果用户绑定的所有终端数量已达到终端管理参数中定义的“单帐号最大绑定终端数”数量限制,则EIA拒绝用户认证,否则允许用户继续认证。
¡ 缺省单帐号在线数量限制:接入用户的接入场景与服务中的接入场景均不匹配时,用户受到缺省单帐号在线数量限制的控制。
¡ 单日累计在线最长时间(分钟):每天允许帐号使用该服务接入网络的总时长,达到该时长后,帐号将被强制下线,且当日不能再次接入。该参数单位是分钟,只支持输入整数,最小值是0,表示不限制每天在线时长,最大值是1440。
¡ 服务描述:针对该服务的简单描述,以方便操作员的日常维护。
表1 EIA中服务后缀的选择
认证连接用户名 |
设备用于认证的Domain |
设备Radius scheme中的命令 |
iMC中服务的后缀 |
X@Y |
Y |
user-name-format with-domain |
Y |
user-name-format without-domain |
无后缀 |
||
X |
[Default Domain] 设备上指定的缺省域 |
user-name-format with-domain |
[Default Domain] |
user-name-format without-domain |
无后缀 |
(3) 单击<确定>按钮,完成增加接入服务。返回接入服务管理页面,可在接入服务列表中查看新增的接入服务,如图13所示。
(1) 选择“自动化”页签,单击导航树中的“业务用户 > 接入用户”菜单项,进入接入用户页面,如图14所示。
(2) 单击<增加>按钮,进入增加接入用户页面,如图15所示。
参数说明:
¡ 用户姓名、证件号码:用户的姓名及证件号码。
¡ 帐号名:唯一标识帐号用户的名称,用户使用该名称申请和使用服务,该名称不能与已有名称相同,不能包含如下特殊字符:#+/?%&=*'@\"[]()<>`和TAB键,且最大长度为200字符。
¡ 密码/确认密码:输入两次相同的密码。
¡ 接入服务:选择之前增加的接入服务。
¡ 其他参数:保持缺省值。
(3) 单击<确定>按钮,完成增加接入用户,返回接入用户页面。可在接入用户列表中查看新增的接入用户,如图16所示。
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 业务参数 > Portal服务”菜单项,进入Portal服务管理页面,如图17所示。
(2) 在“服务类型列表”区域中,单击<增加>按钮,弹出增加服务类型窗口,如图18所示。
参数说明:
¡ 服务类型标识:设备根据用户选择的服务类型确定相应的认证方案,必须与之前增加接入服务中的服务后缀相同。
¡ 服务类型:服务类型标识是设备使用的信息,用户可能无法直观地理解其内在的含义。因此使用服务类型对其进行解释,会显示在Portal认证主页上,便于用户对服务类型的理解。其中,服务类型信息不能为空,并且不能和现有的服务类型信息相同,服务类型的数量不能超过64个。
(3) 单击<确定>按钮,完成增加服务类型。返回服务器配置页面。可在服务类型列表中查看新增的服务类型,如图19所示。
(4) 单击<确定>按钮,完成Portal服务器配置。
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 业务参数 > Portal服务”菜单项,进入Portal服务管理页面。切换至“IP地址组配置”页签,进入IP地址组配置页面,如图20所示。
图20 IP地址组配置
(2) 单击<增加>按钮,进入增加IP地址组页面,如图21所示。
图21 增加IP地址组
(3) 输入IP地址组名,本例为“portal_Address”,并输入起始地址和终止地址IP地址。其中,属于该地址段的终端都要进行认证。
(4) 单击<确定>按钮,完成增加IP地址组,返回IP地址组配置页面。可在IP地址组列表中查看新增的IP地址组,如图22所示。
图22 查看新增的IP地址组
(1) 选择“自动化”页签,单击导航树中的“用户业务 > 业务参数 > Portal服务”菜单项,进入Portal服务管理页面。切换至“设备配置”页签,进入设备配置页面,如图23所示。
(2) 单击<增加>按钮,进入增加设备信息页面,如图24所示。
参数说明:
¡ 设备名:输入设备名称,本例为“zhangsan-Switch”。
¡ 公网IP:Portal接入设备的公网IP地址。
¡ 密钥\确认密钥:输入“movie”。密钥要与设备上配置的Portal服务器密钥保持一致。
¡ 组网方式:在下拉框中选择“直连”。
¡ 其他参数:保持默认值。
(3) 单击<确定>按钮,完成增加设备信息。返回设备配置页面,可在列表中查看新增的设备信息,如图25所示。
(4) 单击列表“操作”列的端口组信息管理图标,进入端口组信息配置页面,如图26所示。
(5) 单击<增加>按钮,进入增加端口组信息页面,如图27所示。
参数说明:
¡ 端口组名:输入端口组的名称,本例为“port-Port”。
¡ 认证方式:在下拉框中选择“CHAP认证”。
¡ IP地址组:选择之前配置的“portal_Address”。
¡ 其他参数:保持默认值。
(6) 单击<确定>按钮,完成增加端口组信息。返回端口组信息配置页面,可在端口组信息配置列表中查看新增的端口组信息,如图28所示。
(1) 选择“自动化”页签,单击“用户业务 > 业务参数 > 接入参数”菜单项,进入业务参数配置页面。切换至“单点登录配置”页签,进入单点登录配置页面,如图29所示。
(2) 单击“Web应用系统 > Portal”项对应配置列的“配置”图标,进入Web应用系统 > Portal页面,按需进行配置,如图30所示。
图30 Web应用系统 > Portal
参数说明:
¡ 启用:如果选中则启用“Web应用系统 > Portal”配置。
¡ 共享密钥:用于Web应用系统与Portal 服务器之间交互的安全性。该项只能输入8位,只能包含如下字符:[A,Z]∪[a,z]∪[0,9]∪{~`!@#$%^&*()_-+{[}]|:";'<,>./}。
¡ 时间戳有效时长:当Web应用系统和Portal服务器完成一次完整成功的报文交互后,两者彼此信任的时长,作为Portal服务器安全性和有效性验证。取值范围5~60分钟。
¡ Portal认证后重定向到URL:Portal认证成功或失败后,打开Web应用系统服务器的URL地址。遵循标准URL格式,即“http://XXXXXXXX”。
接入设备用于控制用户的接入。通过认证的用户可以接入网络,未通过认证的用户无法接入网络。
以下使用Windows的CLI窗口telnet到接入设备并进行配置,具体的命令及其说明如下:
(1) 进入系统视图。
<Device>system-view
System View: return to User View with Ctrl+Z.
(2) 配置RADIUS策略“allpermit”。认证、计费服务器均指向EIA。认证端口、计费端口、共享密钥要与3.2 1. 增加接入设备的配置保持一致。
[Device]radius scheme allpermit
New Radius scheme
[Device-radius-allpermit]primary authentication 192.168.7.220 1812
[Device-radius-allpermit]primary accounting 192.168.7.220 1813
[Device-radius-allpermit]key authentication simple movie
[Device-radius-allpermit]key accounting simple movie
[Device-radius-allpermit]user-name-format with-domain
[Device-radius-allpermit]nas-ip 172.19.254.76
[Device-radius-allpermit]quit
(3) 配置domain域“portal”,引用配置好的“allpermit”策略。domain的名称必须与3.2 3. 增加接入服务中配置的服务后缀保持一致。
[Device]domain portal
[Device-isp-portal]authentication portal radius-scheme allpermit
[Device-isp-portal]authorization portal radius-scheme allpermit
[Device-isp-portal]accounting portal radius-scheme allpermit
[Device-isp-portal]quit
(4) 配置Portal认证服务器:名称为myportal,IP地址指向EIA,key要与3.3.1 3. 设备配置中配置的密钥一致。
[Device]portal server myportal
New portal server added.
[Device-portal-server-myportal]ip 192.168.7.220 key simple movie
[Device-portal-server-myportal]quit
(5) 配置第三方Web服务器的URL。
[Device]portal web-server myportal
New portal web-server added.
[Device-portal-websvr-myportal]url http://ip:port
[Device-portal-websvr-myportal]quit
(6) 在接口GigabitEthernet1/0/16所在VLAN虚接口Vlan-interface 108上开启直接方式的Portal,引用第三方Web服务器myportal,设置发送给Portal认证服务器的Portal报文中的BAS-IP属性值,该BAS-IP需和3.3.1 3. 设备配置中的公网IP保持一致。
[Device]interface Vlan-interface 108
[Device-Vlan-interface108]portal enable method direct
[Device-Vlan-interface108]portal apply web-server myportal
[Device-Vlan-interface108]portal bas-ip 108.108.108.1
[Device-Vlan-interface108]Portal domain portal
[Device-Vlan-interface108]quit
(1) 用户在第三方Web应用系统输入用户名密码进行验证,验证成功后,由第三方Web应用系统自动向Portal系统发起Portal认证。
(2) 认证成功后Portal系统返回单点登录配置中的页面,并弹出心跳页面,用户上线成功。
(3) 可单击心跳页面上的<下线>按钮,断开连接,最终结果如图31所示。
(1) 选择“自动化”页签,单击“用户业务 > 业务参数 > 接入参数”菜单项,进入业务参数配置页面。切换至“单点登录配置”页签,进入单点登录配置页面,如图32所示。
(2) 单击“Web应用系统 > BYOD”项对应配置列的“配置”图标,进入Web应用系统 > BYOD页面,按需进行配置,如图33所示。
图33 Web应用系统 > BYOD
参数说明:
¡ 启用:如果选中则启用“Web应用系统 > BYOD”配置。
¡ 共享密钥:用于第三方应用与BYOD服务器之间交互的安全性。该项只能输入8位,只能输入除空格、Tab字符、“?”、“=”和“\”之外的英文字符。
¡ 时间戳有效时长(分钟):当第三方应用和BYOD服务器完成一次完整成功的报文交互后,两者彼此信任的时长,作为BYOD服务器安全性和有效性验证。取值范围5~60分钟。
接入设备用于控制用户的接入。通过认证的用户可以接入网络,未通过认证的用户无法接入网络。
以下使用Windows的CLI窗口telnet到接入设备并进行配置,具体的命令及其说明如下:
(1) 进入系统视图。
<Device>system-view
System View: return to User View with Ctrl+Z.
(2) 配置RADIUS策略“allpermit”。认证、计费服务器均指向EIA。认证端口、计费端口、共享密钥要与3.2 1. 增加接入设备的配置保持一致。
[Device]radius scheme allpermit
New Radius scheme
[Device-radius-allpermit]primary authentication 192.168.7.220 1812
[Device-radius-allpermit]primary accounting 192.168.7.220 1813
[Device-radius-allpermit]key authentication simple movie
[Device-radius-allpermit]key accounting simple movie
[Device-radius-allpermit]user-name-format with-domain
[Device-radius-allpermit]nas-ip 172.19.254.76
[Device-radius-allpermit]quit
(3) 配置domain域“portal”,引用配置好的“allpermit”策略。domain的名称必须与3.2 3. 增加接入服务中配置的服务后缀保持一致。
[Device]domain portal
[Device-isp-portal]authentication portal radius-scheme allpermit
[Device-isp-portal]authorization portal radius-scheme allpermit
[Device-isp-portal]accounting portal radius-scheme allpermit
[Device-isp-portal]quit
(4) 配置Portal认证服务器:名称为myportal,IP地址指向EIA,key要与3.3.1 3. 设备配置中配置的密钥一致。
[Device]portal server myportal
New portal server added.
[Device-portal-server-myportal]ip 192.168.7.220 key simple movie
[Device-portal-server-myportal]quit
(5) 配置第三方Web服务器的URL。
[Device]portal web-server myportal
New portal web-server added.
[Device-portal-websvr-myportal]url http://ip:port
[Device-portal-websvr-myportal]quit
(6) 在接口GigabitEthernet1/0/16所在VLAN虚接口Vlan-interface 108上开启直接方式的Portal,引用第三方Web服务器myportal,设置发送给Portal认证服务器的Portal报文中的BAS-IP属性值,该BAS-IP需和3.3.1 3. 设备配置中的公网IP保持一致。
[Device]interface Vlan-interface 108
[Device-Vlan-interface108]portal enable method direct
[Device-Vlan-interface108]portal apply web-server myportal
[Device-Vlan-interface108]portal bas-ip 108.108.108.1
[Device-Vlan-interface108]Portal domain portal
[Device-Vlan-interface108]quit
用户在第三方Web应用系统输入用户名密码进行验证,验证成功后,由第三方Web应用系统自动向BYOD系统发起BYOD认证,认证成功后,接入终端页面会有该用户绑定的终端信息,终端可正常访问网络,如图34所示。
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.commons.codec.binary.Base64; // 本样例的Base64 API, 来自Apache组织的工具类.
/**
* DES加解密
*
* @author
*/
public class DesCipher {
/**
* 加密
*
* @param plainText
* 待加密的原始字符串
* @param key
* 共享密钥
* @return 加密后并经过Base64编码的字符串
*/
public static String encryptData(String plainText, String key) {
Cipher encryptDesCipher = null;
try {
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("GBK")); // GBK
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey desSecretKey = factory.generateSecret(desKeySpec);
encryptDesCipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // DES/ECB/PKCS5Padding
encryptDesCipher.init(1, desSecretKey);
byte[] cryptoText = null;
cryptoText = encryptDesCipher.doFinal(plainText.getBytes("GBK")); // GBK
if (cryptoText != null) {
return new String(Base64.encodeBase64(cryptoText), "GBK"); // GBK
}
} catch (Throwable e) {
e.printStackTrace();
return null;
}
return null;
}
/**
* 解密
*
* @param base64EncryptInfo
* 待解密的字符串
* @param key
* 密钥
* @return 解密后的字符串
* @throws UnsupportedEncodingException
*/
public static String decryptData(String base64EncryptInfo, String key) {
try {
byte[] encryptInfo = null;
if (base64EncryptInfo != null) {
encryptInfo = Base64.decodeBase64(base64EncryptInfo.getBytes("GBK")); // GBK
}
Cipher decryptDesCipher = null;
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("GBK")); // GBK
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey desSecretKey = factory.generateSecret(desKeySpec);
decryptDesCipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); // DES/ECB/PKCS5Padding
decryptDesCipher.init(2, desSecretKey);
byte[] plainText = null;
plainText = decryptDesCipher.doFinal(encryptInfo);
if (plainText != null) {
return new String(plainText, "GBK"); // GBK
}
} catch (Throwable e) {
e.printStackTrace();
return null;
}
return null;
}
}
import org.apache.commons.codec.binary.Base64; // 本样例的Base64 API, 来自Apache组织的工具类.
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
/**
* DES加解密
*
* @author
*/
public class UserInfoUtil {
/**
* 合成userinfo串
* @param username 名
* @param password 密码
* @param timestamp 时间戳
* @param key 解密密钥
* @return
*/
public static String composeUserinfo(String username, String password, long timestamp, String key) {
try {
StringBuilder userInfo = (new StringBuilder())
.append("username=").append(new String(Base64.encodeBase64(username.getBytes("GBK")), "GBK"))
.append(",password=").append(new String(Base64.encodeBase64(password.getBytes("GBK")), "GBK"))
.append(",timestamp=").append(timestamp);
String userInfoStr = DesCipher.encryptData(userInfo.toString(), key);
userInfoStr = URLEncoder.encode(userInfoStr, "UTF-8"); // UTF-8
return userInfoStr;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
/**
* 从userinfo中解析出用户名/密码
* @param str 处于加密形态的userinfo
* @param key 解密密钥
* @return
*/
public static Map<String, String> analyzeUserinfo(String str, String key) {
try {
str = URLDecoder.decode(str, "UTF-8"); // UTF-8
str = DesCipher.decryptData(str, key);
String[] userinfo = str.split(",");
Map<String, String> paras = new HashMap<String, String>();
for (String nameAndVal : userinfo) {
String[] nv = nameAndVal.split("=");
if("username".equals(nv[0]) || "password".equals(nv[0])) {
nv[1] = new String(Base64.decodeBase64(nv[1].getBytes("GBK")), "GBK");
}
paras.put(nv[0], nv[1]);
}
return paras;
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* DES加解密
*
* @author
*/
public class HttpUtil {
/**
* 请求某个URL。
* @param url URL
* @param method 请求方式
* @param accept accept
* @return 请求结果
*/
public static String requestWebAppUrl(String url, String method, String accept) {
HttpURLConnection con;
InputStream input = null;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try {
con = (HttpURLConnection)(new URL(url)).openConnection();
con.setRequestMethod(method);
con.setConnectTimeout(5000);
con.setReadTimeout(50000);
con.setDoOutput(false);
con.setRequestProperty("Accept", accept);
con.setRequestProperty("Accept-Language", "zh-cn,en-us;q=0.5");
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0");
input = con.getInputStream();
byte[] buff = new byte[256];
int len = -1;
while ((len = input.read(buff)) != -1) {
buffer.write(buff,0,len);
}
String str = buffer.toString("UTF-8"); // UTF-8
return str;
} catch (Throwable e) {
return null;
} finally {
if (input != null) {
try {
input.close();
} catch (Throwable e) {
}
}
}
}
}