创建一个简单的 MDM server(1)
前提:已获得 APNS 证书 ,已完毕 MDM 配置描写叙述文件的制作。请參考《 MDM 证书申请流程 》一文和《配置MDM Provisioning Profile》。
环境:OSX 10.9.2,JDK 1.6。Eclipse JavaEE Helois,Tomcat 7.0
一、前言
《THE IOS MDMPROTOCOL》(即Inside Apple MDM)一文中描写叙述了一个简单 MDM Server Python 实现(server.py)。
笔者也曾參照此文配置,但在安装M2Crypto 一步时遇到一个 cc 參数没有定义错误。实在无法进行下去,因此不得不放弃。在參照《基于IOS上MDM技术相关资料整理及汇总》一文时,发现其使用了商业SSL证书(StartSSL)。而笔者使用的自签名SSL证书,有些步骤不太一样 ,另外在一些关键点也须要读者自己摸索,因此有了本文的诞生。
二、准备
无论 APNS 还是 MDM,都须要server实现 https。如果我们使用 Eclipse 调试 Tomcat,则须要改动 Servers 项目以下的Tomcat 配置文件 server.xml。详细过程请參考《开启 Tomcat https 服务》。
三、 实现 checkin URL
MDM 须要实现完整 APNS 服务,对此我们採用的是第三方的 java apns 实现。
主要是 notnoop 的 Java apns(不是google 的 JavaPNS),此外,还有 xmlwise ,用于解析苹果的 plist 文档。
java apns有两个包:apns-0.1.5.jar 和 apns-0.1.5-jar-with-dependencies.jar包。
前者是 API,后者是依赖包。
xmlwise 就一个包:xmlwise-1_2.jar。
数据库採用 mysql。因此也须要 mysql-connector-java-5.1.2-bin.jar包。
此外java apns 使用了slf4j。即 slf4j-simple-1.7.7.jar。
将 MDM push 证书 mdm_push.p12 和 provisioning 配置描写叙述文件 client.mobileconfig 放到WebContent 文件夹下。
用 MySQLWorkbench 连上 mysql 数据库,创建两张表。用于设备注冊:
CREATE TABLE `Authenticate` (
`UDID` varchar(40) NOT NULL,
`Topic` varchar(200) DEFAULTNULL,
`timestamp` timestamp NULLDEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`UDID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `TokenUpdate` (
`UDID` varchar(40) NOT NULL,
`Topic` varchar(200) DEFAULTNULL,
`PushMagic` varchar(200)DEFAULT NULL,
`Token` varchar(200) DEFAULTNULL,
`UnlockToken` blob,
`timestamp` timestamp NULLDEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`UDID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
首先看注冊服务。设备注冊由Servlet checkin 实现。其 doPut 方法例如以下:
System.out.println("*********ReceivedMessage:***********\n"+plistStr);
try{
Map<String,Object>plist=Plist.fromXml(plistStr);
if(plist!=null){
StringMessageType=plist.get("MessageType").toString();
if(MessageType.equals("Authenticate")){
Authenticate au=newAuthenticate(plist.get("UDID").toString(),plist.get("Topic").toString());
au.save();
}elseif(MessageType.equals("TokenUpdate")){
Stringregex="Token</key>\\s*<data>\\s*([^\\s]*)\\s*</data>";
String tokenStr=Utils.regxCatch(plistStr,regex);
System.out.println("catches tokens:"+tokenStr);
TokenUpdate tu=new TokenUpdate(plist);
tu.Token=tokenStr;
tu.save();
}
response.getWriter().println(Utils.emptyPlist());
}
}catch(Exceptione){
e.printStackTrace();
}
checkin 主要处理与注冊相关的两种消息:Authenticate 和 TokenUpdate。
在设备注冊中,server首先收到Authenticate 消息,checkin 将之计入 Authenticate 表,然后返回一个空的 plist 文件。设备随后会发来TokenUpdate 消息。checkin 也会将之存到 TokenUpdate 表并返回空 plist 文件。在 TokenUpdate 消息的处理中,checkin获取的是 UDID、device token、push magic和 unlock 等 MDM push中将要用到的重要字段。
当中,token(即 APNS 中的 device token)须要特别注意。
由于在苹果的文档中说,这是一个32位长度的字符串。
实际上我们都知道APNS 中,device token 是一个 byte 数组。
在 TokenUpdate 消息中,iOS 将 device token 的 byte 数组进行了base64 编码,结果变成了一个 44 字节长度的 string。也就是说在 TokenUpdate 消息中。<token>字段的值类型应该是<string>,而不应该是消息中定义的<data>。
一个典型的 TokenUpdate 消息,其 token 描写叙述例如以下:
<key>Token</key>
<data> [ 32 byte string, base64 encoded,redacted ]</data>
显然,这里的<data>必须换成<string>。xmlwise 包中的 Plist 类才干正确解析。
由于在 Plist 类中,对于 plist 文件里的数据类型<data>会被解析为 byte 数组而不是字符串。
因此 checkin 在处理 TokenUpdate 消息时。採取了额外的手段来获取 token 字段,即正则捕获。
执行 Tomcat server,将 iPad 接入server统一 wifi 网络,然后在浏览器中訪问描写叙述文件地址:
https://192.168.2.1:8443/mdmtest/client.mobileconfig
此时 safari 将调用设置程序,在客户端安装 mdm 配置描写叙述文件。当你点击“安装”button,iPad 会请求 checkin URL地址,并发送Authenticate 消息和 TokenUpdate 消息。你能够在数据库中查看到这两条消息。
创建一个简单的 MDM server(1)的更多相关文章
- 使用Python创建一个简易的Web Server
Python 2.x中自带了SimpleHTTPServer模块,到Python3.x中,该模块被合并到了http.server模块中.使用该模块,可以快速创建一个简易的Web服务器. 我们在C:\U ...
- spring cloud 创建一个简单Eureka Server
在Spring Cloud实现一个Eureka Server是一件非常简单的事情.下面我们来写一个Eureka Server DEMO. 编码 父项目pom.xml <?xml version= ...
- 《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型
第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...
- 编写一个简单的Web Server
编写一个简单的Web Server其实是轻而易举的.如果我们只是想托管一些HTML页面,我们可以这么实现: 在VS2013中创建一个C# 控制台程序 编写一个字符串扩展方法类,主要用于在URL中截取文 ...
- [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序
近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...
- node创建一个简单的web服务
本文将如何用node创建一个简单的web服务,过程也很简单呢~ 开始之前要先安装node.js 1.创建一个最简单的服务 // server.js const http = require('http ...
- 用go和zk实现一个简单的分布式server
golang的zk客户端 最近打算写个简单的配置中心,考虑到实现便捷性,语言选择了go,由于其中计划用到zk,就调研了下golang的zk客户端,并实现了个简单的分布式server.最终找到了两个,地 ...
- 创建一个简单的 http 服务器
创建一个简单的 http 服务器 直接在 目录下运行 当前的目录即可是root 目录 默认端口8000 应该可以加参数修改端口号 Python2 python -m SimpleHTTPServer ...
- 如何创建一个简单 APT 仓库
0. 无废话版本 需求: 有一堆 .deb 包,想把它们做成一个 APT 仓库,这样就可以用apk install pkgname进行安装了,这样一方面自己可以规避 dpkg -i xxx.deb 时 ...
随机推荐
- hdu1695 容斥原理 莫比乌斯反演
给定两个数b,d,问[1,b]和[1,d]区间上有多少对互质的数.(x,y)和(y,x)算一个. 对于[1,b]部分,用欧拉函数直接求.对于大于b的部分,求n在[1,b]上有多少个互质的数,用容斥原理 ...
- SecureCRT 详细使用教程和技巧
SecureCRT 常用技巧 0.在secureCRT里切换不同的窗口:ctrl+tab. 复制:[ctrl] + [shift] + c 粘贴:[ctrl] + [shift] + v ...
- Linux 通过cron定期执行 php文件(转)
Linux 通过cron定期执行 php文件 补充几点: 1. 要在php文件头加上解释器的路径,通常是 #!/usr/bin/php 2. 授予要执行的php文件执行权限 chmod a+x x ...
- 《JAVA与模式》之有感
陆陆续续看了gof,大话设计模式等books,对于设计模式仍然是徘徊于门外,随偶有感悟,然久必忘记,是实则悟性太低. 因此作此文,结合博客中一系列关于设计模式的博文,加深对设计模式的理解,同时备自己随 ...
- Sql Server添加单引号
" ' "(单引号)的运用:在sql server中,两个" ' "(单引号)在拼接字符串的情况下运用,就是表示拼接上了一个" ' "单引号 ...
- docker lnmp php
使用 Docker 构建 LNMP 环境 https://segmentfault.com/a/1190000008833012 Docker 快速上手指南 https://segmentfault. ...
- vue中如何实现数据的双向绑定
vue中如何实现数据的双向绑定 实现视图变化数据跟着变:分两步,上面get中的为第二步(即再次读取的时候会调用get方法得到之前设置的值,以此来实现动态改变) 由于直接写obj.name = this ...
- unity5 Edit Collider
按下Edit Collider按钮,视图中Collider线框中出现控制点,可以通过拖动控制点对Collider进行调整.
- shell case语法
在阅读hadoop相关的脚本文件时,遇到case语句,好久不写shell,忘了不少,复习下shell的case语句: 运行结果: ...
- SpringBoot进阶
一.表单验证 二.AOP处理请求 AOP是一种编程范式.与语言无关,是一种程序设计思想. 面向过程到面向对象.换个角度看世界,换个姿势处理问题. 2.1AOP实例-http请求 MAVEN添加依赖:o ...