添加一个 Incoming MAC 适配器
MAC(消息认证码)是一种用于确定单点登录(SSO)请求完整性的方法。你必须在源系统上开发逻辑来生成MAC,UAS服务可以验证该MAC。
配置无人机设置
在无人机设置界面,选择添加认证适配器。填写字段如下:
字段 | 描述 |
|---|---|
别名 | 这是适配器的独特名称,用于URL中。别名将以所有小写字母存储,且不应包含任何特殊的URL字符。 |
已启用 | 该开关决定适配器是否可用。 |
授权类型 | MAC |
使用外接适配器 | 选择用于向外部服务进行出站认证的认证适配器。如果没有选择,默认的出站适配器将被使用。 |
调试启用 | 该开关决定是否将调试语句写入日志以进行故障排除。 |
受限用户 | 输入一个逗号分隔的用户名列表,这些用户无法使用该适配器。 |
算法 |
|
参数 | 这就是参数名与标准值之间的映射。例如,你提供的查询字符串有一个参数值叫“time”,它应该映射到预期的“Timestamp”值。 |
认证 | 包含MAC认证签名的参数。推荐值:认证 |
格林威治标准时间时间 | 包含时间戳的参数。推荐值:时间戳 |
用户ID | 包含用户 ID 的参数(用户的 username 或 batch_uid/external ID;这取决于您在 Blackboard 如何配置 SAML 身份验证提供程序)。推荐值:userId |
课程 ID | 包含课程ID的参数。这可以是 Blackboard 内部课程标识符(_9999_1 格式)或 batch_uid/external ID。系统会把看起来像内部课程标识符的项目视为内部标识符,其他的视为外部ID。推荐值:courseId |
向前 | 包含 Learn 内转发的 URL 的参数。这可能包含或不包含 Blackboard host name。推荐值:前进 |
时间戳 Delta | 请求生成与认证适配器服务接收请求之间的时间戳之间允许的差值(以毫秒为单位)。推荐价值:10,000 - 60,000 |
MAC参数 | 这里列出的任何额外参数都会被纳入MAC计算中(用户ID和时间戳始终包含在内)。 |
秘密 | 用于计算MAC的共享密钥。
在远程系统中,将共享秘密存放在安全目录中。 保存后,这个数值会被隐藏,你无法访问,但可以更改。 |
错误页面帮助文本 | 输入当认证或配置出现问题时,错误页面上会出现的文本。 |
禁用无发声追踪 | 请开启此开关以便排查故障,以便重新使用认证请求。出于安全考虑,我们建议您关闭此开关,以便启用无一次性追踪。 |
启用用户配置 | 开启此开关,允许用户根据MAC请求中提供的信息自动创建。 |
启用注册配置 | 开启此开关,允许在无注册且提供课程ID时自动创建注册。 |
允许更改注册可用性 | 开启此开关,允许系统启用已存在但已禁用的注册。 |
选择保存以保存你的配置。
配置适配器的URL是https://{region}.扩展.blackboard.com/api/v2/authadapters/sites/{siteId}/auth/{alias}。
在可信系统上生成MAC地址
为了正确认证用户,受信任系统必须能够生成有效的MAC(消息认证码)并随单点登录请求发送。该MAC用于确定单点登录请求的完整性。生成安全MAC地址:
按参数名称字母顺序排序参数(时间戳、用户ID、请求参数中用于MAC设置的额外参数)。
将参数值与排序后的参数名称串接成一个字符串。
将共享秘密附加到第二步获得的字符串后。
用MD5算法将字符串加密成16字节字符串。
将16字节字符串转换为32字节的字母数字(十六进制)字符串,使其对网址友好。
例如
本示例使用请求参数字符串的默认值和共享秘密值“blackboard”,同时“courseId”也被定义为Mac请求参数中的额外参数。
排序参数(括号内参数值):courseId(
TC-101)、时间戳(1268769454017)、userId(test01)参数值串接:
TC-1011268769454017test01共享秘密附加:
TC-1011268769454017test01blackboard加密字符串:
ŒIV ̈Báƒež©dxºvqâ转换字符串:
8c4956a842e183659ea96478ba7671e2
Mac 脚本示例
Java 示例
安全算法:
/**
* Calculates a secure MAC (message authentication code) from an array of strings and shared secret.
* @param values – Parameters must first be sorted alphabetically by parameter name, then the values of these sorted parameters passed to calculateSecureMac
* @param secret - the shared secret
* @return The calculated MAC
*/
private String calculateSecureMAC (final String[]
values, final String secret) throws
NoSuchAlgorithmException
{
// concatenate param values
final int size = values.length;
String paramString = "";
for(int i=0; i<size; i++)
{
paramString += values[i];
}
// get md5 hash from ascii value and secret
final MessageDigest md = MessageDigest.getInstance("MD5");
final byte[] hashBytes = md.digest((paramString + secret).getBytes());
md.reset();
// convert to hex
String mac = "";
String hexByte;
for (int k=0; k<hashBytes.length; k++)
{
hexByte = Integer.toHexString(hashBytes[k] < 0 ? hashBytes[k] + 256 : hashBytes[k]);
mac += (hexByte.length()==1) ? "0" + hexByte : hexByte;
}
return mac;
}PHP 示例
安全算法:
/* Calculates a MAC (message authentication code) from an array of strings and a secret.
Sort request parameters alphabetically by parameter name first, then pass values of sorted
parameters and shared secret to calculateSecureMac */
function calculateSecureMac($params, $secret)
{
// concatenate param values
$data = implode('', $params);
// get md5 of concatenated param values and secret
$mac = md5($data . $secret);
return $mac;
}Perl 示例
安全算法:
use Digest::MD5;
# Calculates a MAC (message authentication code) from an array of strings and a secret. Sort request parameters alphabetically by parameter name first, then pass values of sorted parameters and shared secret to calculateSecureMac
sub calculateSecureMac
{
my @args = @_;
$secret = pop(@args);
# concatenate param values
$data = join("", @args);
# get md5 of concatenated param values and secret
$ctx = Digest::MD5->new;
$ctx->add($data . $secret);
$mac = $ctx->hexdigest;
return $mac;
}