通过APNS发送MDM的恢复出厂设置命令

分类: 首页- >MDM专栏 | 阅读: 4498 | 评论: 0 | 2014-07-24 16:16:25 
摘要:mdm的清除数据功能和锁屏功能基本上一样的,具体的参见下面的说明: 1、通过MDM的p12证书推送一个MDM消息到APNS服务器 按照文档BH_US_11_Schuetz_InsideAppleMDM_WP.pdf上面的介绍,我们向APNS推送任何命令都应该先发送一个消息给Apple的推送服务器
其实,mdm的清除数据功能和锁屏功能基本上一样的,具体的参见下面的说明:
1、通过MDM的p12证书推送一个MDM消息到APNS服务器
按照文档BH_US_11_Schuetz_InsideAppleMDM_WP.pdf上面的介绍,我们向APNS推送任何命令都应该先发送一个消息给Apple的推送服务器,例如:我们要实现锁屏功能,那么就应该在推送一个类似这样的消息:{"aps":{},"mdm":"996ac527-9993-4a0a-8528-60b2b3c2f52b"}的时候在我们自己的MDM Server记录一条清除数据命令的记录,参考我这里的代码:

   /**
     * 擦除设备数据功能
     * @throws Exception
     */
    @GET
    @Path("/erase/:deviceId")
    public void deviceErase() throws Exception {
        System.out.println("-------------------Erase Start---------------");
        //返回到页面
        Map map = new HashMap();
        /**获取MDM推送相关的Token、PushMagic等设备信息**/
        String deviceId = ControllerContext.getContext().getPathParamMap().get("deviceId");
        DBService dbService = ControllerContext.getContext().getDBService(Mdm.class);
        Mdm mdm = (Mdm) dbService.find("deviceId = ?", new Object[]{deviceId});
        /**对设备进行锁屏**/
        String pemFile = PushConfig.getConfig("APNS_P12MDM");
        HttpServletRequest request = (HttpServletRequest) ControllerContext.getContext().getHttpRequest();
        String pemPath = request.getRealPath("mdmtool") + pemFile;
        int pushState = PushUtils.singleMDMLockPush(pemPath, mdm);
        if (pushState == 1) {
            DBService commandService = ControllerContext.getContext().getDBService(Command.class);
            Command command = new Command();
            command.setCommand(MdmUtils.Erase);
            command.setDeviceId(deviceId);
            command.setDoIt("0");
            commandService.saveOrUpdate(command);
            map.put("state", "1");
            map.put("msg", "擦除数据命令发送成功");
        } else {
            map.put("state", "0");
            map.put("msg", "擦除数据命令发送失败");
        }
        System.out.println("-------------------Erase End---------------");
        toResult(Response.Status.OK.getStatusCode(), map);
    }

其中上面的PushUtils.singleMDMLockPush(pemPath, mdm);中的命令就是发送一个MDM的数据格式为:{"aps":{},"mdm":"996ac527-9993-4a0a-8528-60b2b3c2f52b"}这样的推送信息,这个是所有的推送都是一样的,包括锁屏,这样的推送信息来告诉设备(Device)MDM Server需要连接设备执行操作了。其中代码参考:

   /**
     * 向单个iPhone手机推送Lock消息.
     * @param  mdm    推送参数
     * @return pushState    返回执行状态(1:成功,0:失败)
     */
    public static int singleMDMLockPush(String p12Path,Mdm mdm) {
        int pushState = 0 ;
        try {
            ApnsService service =
                    APNS.newService()
                            .withCert(p12Path,MDMPASS)
                            .withProductionDestination()
                            .build();
            String mdmPayload = APNS.newPayload().customField("mdm", mdm.getPushMagic()).build();
            service.push(mdm.getToken(), mdmPayload);
            pushState = 1;
            System.out.println("推送信息已发送!");
        } catch (Exception e) {
            System.out.println("出错了:"+e.getMessage());
            pushState = 0;
        }
        return pushState;
    }

其中上面的mdm.getToken()这个Token是在TokenUpdate的时候获取的原始Token经过解码处理的Token,其中在TokenUpdate获取是我们这样转化了一次Token,参见如下的工具方法代码:

    /**
     * 将通过TokenUpdate获取的原始Token转化成16进制新的Token
     * @param OriToken
     * @return
     * @throws IOException
     */
    public static String parseToken(String OriToken) throws IOException{
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] decodedBytes = decoder.decodeBuffer(OriToken);
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < decodedBytes.length; ++i) {
            buf.append(String.format("%02x", decodedBytes[i]));
        }
        String Token = buf.toString();
        return  Token;
    }
其中的OriToken是这样的格式: The Tokenis a 32-byte binary value, presented as Base64 encoded text(文档原话)
 

2、设备(Device)收到推送信息后来请求服务器,服务器发送清除数据(Erase)命令:
当设备送到MDM的推送信息后,设备就会马上来连接MDM Server服务器的Server URL并传递一个类似如下的数据过来,例如:

PUT: /server
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Status</key>
<string>Idle</string>
<key>UDID</key>
<string> [ redacted ] </string>
</dict>
</plist>

其中“Status”为“Idle”时表示设备现在空闲,可以执行相应的操作,那么我们的MDM Server收到这样的数据后,就马上查询数据库回去需要执行的命令列表返回一个并组装成设备需要的类似xml格式给设备,代码参考:

 /************判断状态是否为:Idle,然后查询数据库的命令数据**********/
 /**执行命令**/
 Command command = (Command) commandService.findHql("from Command where deviceId=? and doIt=? order by createTime asc", new Object[]{deviceId, "0"});
 /**发送清除数据命令**/
 String commandString = MdmUtils.getCommandPList(MdmUtils.Erase, command.getId());
 command.setDoIt("1");
 commandService.saveOrUpdate(command);
 System.out.println("-------------------EraseDevice Start---------------");
 //设置下载的头信息
 HttpServletResponse response = (HttpServletResponse) ControllerContext.getContext().getHttpResponse();
 response.setHeader("content-type", "application/xml;charset=UTF-8");
 response.setCharacterEncoding("UTF-8");
 String configTitle = "Mbaike_EraseDevice";
 response.setHeader("Content-Disposition", "attachment; filename=" + configTitle + ".plist");
 PrintWriter sos = response.getWriter();
 System.out.println("-------------------EraseDevice End---------------");
 sos.write(commandString);
 sos.flush();
 sos.close();

上面的代码其实就是提供一个xml格式文件的下载,其中的MdmUtils.getCommandPList(MdmUtils.Lock, command.getId());就是一个组装命令的过程,具体代码参考:

    /**
     * 发送命令的pList格式的模板文件
     * @return
     */
    public static String getCommandPList(String command,String commandUUID){
        StringBuffer backString = new StringBuffer();
        backString.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        backString.append("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"");
        backString.append("\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
        backString.append("<plist version=\"1.0\"><dict><key>Command</key><dict><key>RequestType</key><string>");
        backString.append(command);
        backString.append("</string></dict><key>CommandUUID</key><string>");
        backString.append(commandUUID);
        backString.append("</string></dict></plist>");
        return backString.toString();
    }

3、设备(Device)执行完命令,然后返回结果:
当设备执行完锁屏命令后,设备会返回一个类似这样的数据给MDM Server,代码参考:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CommandUUID</key>
<string></string>
<key>Status</key>
<string>Acknowledged</string>
<key>UDID</key>
<string> [ redacted ] </string>
</dict>
</plist>

服务器收到这样的数据后,会根据返回的CommandUUID来查询服务器的命令数据并更新数据的状态,代码参考:

System.out.println("-------------------OtherResult Start---------------");
Map<String, String> plistMap = MdmUtils.parseCommand(info);
String CommandUUID = plistMap.get("CommandUUID");
Command command = (Command) ServiceUtil.getEntityById(Command.class, CommandUUID);
if (command != null) {
      command.setResult(MdmUtils.Acknowledged);
      command.setDoIt("2");
      commandService.saveOrUpdate(command);
}
System.out.println("-------------------OtherResult End---------------");

到此,MDM的清除数据功能讲解完成。具体的也可以参考MDM的锁屏文章:通过APNS发送MDM的锁屏命令
 声明:www.mbaike.net 博客文章版权属于作者,受法律保护。未经作者同意不得转载。
标签 APNS MDM TokenUpdate
相关搜索

共有 0 条网友评论

还木有留言,还不抢沙发?

发布评论:

昵称: 邮箱: 验证码:
文明上网,理性发言!
© 移动互联百科(www.mbaike.net) | WAP站点 | 站长QQ:459104018 | 备案号:蜀ICP备14008230号-2