如何使用saml2.0和adfs实施api与cli访问联合控制
发布网友
发布时间:2022-04-24 01:25
我来回答
共1个回答
热心网友
时间:2022-04-12 11:42
AWS支持使用SAML(安全断言标记语言) 2.0进行身份联合。使用SAML,你可以配置你的AWS账户与你的身份提供商(IdP)整合。一旦配置,你组织的身份提供商就会对你的联合用户进行验证和授权,然后联合用户可以使用单点登录方法登录到AWS管理控制台。这不仅可以使你的用户免于记住另一个用户名和密码,也是简化了管理员的身份管理过程。当你的联合用户想访问AWS管理控制台,这种方法是有效的。但是当他们想使用AWS CLI或以程序方式调用AWS API时,将会怎么样呢?
在本文中,我将向你展示如何对你的用户实施联合的API与CLI访问。本帖中提供的举例使用了AWS Python SDK工具和一些附加的客户端侧的集成代码。如果你有用户需要这种访问控制,实施该方案可以使你对这些用户的管理轻松自如。
让我们从快速地了解我们的目标开始。
janedoe@Ubuntu64:/tmp$ ./samlapi.py
Username: AD\janedoe
Password: ****************
Please choose the role you would like to assume:
[ 0 ]: arn:aws:iam::012345678987:role/ADFS-Administrators
[ 1 ]: arn:aws:iam::012345678987:role/ADFS-Operators
Selection: 1
---------------------------------------------------------------
Your new access key pair has been stored in the aws configuration
file /home/janedoe/.aws/credentials under the saml profile.
Note that it will expire at 2015-05-26T17:16:20Z.
After this time you may safely rerun this script to refresh your
access key pair.
To use this credential call the aws cli with the --profile option
(e.g. aws --profile saml ec2 describe-instances).
---------------------------------------------------------------
Simple API example listing all s3 buckets:
[<Bucket: mybucket1>, <Bucket: mybucket2>, <Bucket: mybucket3>,
<Bucket: mybucket4>, <Bucket: mybucket5>]
从上面的输出结果中我们清楚地看到了什么?
1. 系统提示联合用户输入Active Directory(动态目录)证书。这些证书用来与配置的IdP进行比较以对用户进行验证和授权。
2. 系统检查返回的SAML断言,确定用户被授权承担的IAM(身份及访问管理)角色。用户选择了她期望的角色后,系统使用AWS STS(安全令牌服务)提取临时的安全证书。
3. 系统自动地将这些证书写入她本地的AWS证书文件,她可以开始发出AWS API或CLI调用指令。
4. 得到该样例,为你的组织对样例进行定制后,你就可以在保持AWS IAM服务提供的控制的同时,使用组织的证书来提高你的AWS API和CLI界面的能力和自动化程度。
本帖将会集中讲述如何使用微软动态目录联合服务(AD FS)。但是如果你正在使用其他供应商的同类产品,请不要感到失望因为基本的组件应该可以与其他常见的IdP配合运转的。
为了能够紧跟本帖的讲述,你必须已经:
入门
1. 使用你的组织证书将AD FS正确地与你的AWS账户进行了集成,以便能够访问控制台。如果你需要设置说明,请参考 Enabling Federation to AWS using Windows Active Directory, ADFS, and SAML 2.0。
2. 已在本地工作站安装了新版本(2.36或更新)的AWS Python SDK工具。
3. 获取了最小限度的AWS证书文件(例如:~/.aws/credentials),并将文件中的如下内容调整到你首选的区域和输出格式。
重要提示:AWS访问密钥对并没有在上面的结构中配置因为最初的AWS STS调用是由值得信任的IdP返回的SAML断言进行验证的。所有后续的API/CLI调用都是由包含在AWS STS令牌中的密钥对进行验证的。想要获取更多信息,请参考 Giving AWS Console Access to Federated Users Using SAML
首先,你需要安装不属于Python核心发行版的两个模块,具体说,就是beautifulsoup4和requests-ntlm。有若干种方法可以安装着两个模块,但是包含在Python 2.7.9或更新版本中的pip工具,使模块安装变得很容易。你只需运行如下两个命令即可:
[default]
output = json
region = us-west-2
aws_access_key_id =
aws_secret_access_key =
首先运行下面的命令:
<u>pip install beautifulsoup4</u>
然后运行下面的命令:
pip install requests-ntlm
你应该会得到一些与如下截图类似的输出结果:
AWS联合过程利用IdP发起的登录方法。在最后的准备步骤中,你需要确定具体的被用来引发登录的URL。以基本的IdP引发登录的URL为起点(该URL就是你用来联合访问SAML依赖各方的URL,SAML依赖各方包括AWS管理控制台)。在本例中,我使用的是AD FS 2.0。在该版本中,URL的格式为ofhttps://<fqdn>/adfs/ls/IdpInitiatedSignOn.aspx。如果我将该URL输入浏览器的地址栏,我将会看到一个网站选择页面,
为了构造你所需的URL,将原来的IdP引发登录URL与查询字符串?loginToRp=urn:amazon:webservices连接。构造好的URL应呈现的形式是ofhttps://<fqdn>/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices。保存该URL因为在后面的叙述中它将被称为idpentryurl变量。如果你将这个串联的URL输出浏览器的地址栏,你应该仍然可以实现AD FS IdP引发登录过程。但是,你绕过了网站选择页面,在验证完演练所需的URL后直接进入AWS管理控制台。如果感兴趣的话,你可以访问Microsoft’s website去查看关于查询字符串的文档。
重要提示:务必密切注意URL中主机名称的大写。AD FS在验证过程中会使用主机名称,任何在大小写方面的不匹配都会导致验证失败。
检查代码
既然你已经浏览了上面“入门”部分的步骤,你可以开始组合控制联合API与CLI访问的集成代码了。我将会详细地解释这一过程以便你可以跟随我的节奏。首先,让我们进行一些基本的导入和变量设置。
#!/usr/bin/python
import sys
import boto.sts
import boto.s3
import requests
import getpass
import ConfigParser
import base64
import xml.etree.ElementTree as ET
from bs4 import BeautifulSoup
from os.path import expanser
from urlparse import urlparse, urlunparse
from requests_ntlm import HttpNtlmAuth
##########################################################################
# Variables
# region: The default AWS region that this script will connect
# to for all API calls
region = 'us-west-2'
# output format: The AWS CLI output format that will be configured in the
# saml profile (affects subsequent CLI calls)
outputformat = 'json'
# awsconfigfile: The file where this script will store the temp
# credentials under the saml profile
awsconfigfile = '/.aws/credentials'
# SSL certificate verification: Whether or not strict certificate
# verification is done, False should only be used for dev/test
sslverification = True
# idpentryurl: The initial URL that starts the authentication process.
idpentryurl = 'https://<fqdn>/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices'
##########################################################################
将上述代码中的变量调整为针对你的具体的区域(如us-west-2,us-east-1等等)和格式喜好(例如json,文本,或表格),然后插入本帖中上一部分变量idpentryurl的值。
基本环境搭建起来后,提示用户,从标准输入中检索用户的证书。在本帖的后面我将会讨论我们是如何支持其他的证书形式的。
# Get the federated credentials from the user
print "Username:",
username = raw_input()
password = getpass.getpass()
print ''
位于第一行打印语句“Username”后面的逗号可能看起来像是一个缺陷,实际上它是Python为了防止第一行打印语句添加换行符而使用的小技巧。你也将会注意到getpass()这一方法的使用,这一方法是为了防止密码被显示在输出结果中。
下一步,我们使用Python请求模块组合验证信息,用公式表示向IdP发送的HTTPS请求,正如下面的片段所示。假设验证成功,AD FS返回的响应消息会包含SAML断言。