月度归档:2013年12月

收藏 scp (Secure copy)协议

收藏一篇描述scp协议的文章。 很难找到的。

原文链接:https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works

为了防止原文链接失效, 我把内容粘贴过来。

==================================================分割线=============

How the SCP protocol works

By janp on Jul 09, 2007

Have you ever wondered how the scp and rcp commands worked? The first time I did I haven't found any documentation on the subject. There is no RFC, no draft, not even README file describing it. After reading the source code I tried again and realized that old version of rcp.c might be really the only original documentation available. And since I worked on a couple of bugs in our scp(1) some time ago I put a note in my todo list to write something about it, for the next time I'm going to need it.

A very short history of the protocol

The rcp command appeared in 4.2BSD in 1982, with this manual page. Since then it evolved a little bit which means that old rcp can't work together with current rcp in all cases. The same protocol was used in ssh-1.2.x implementation which was later used as a base for OpenSSH. Since Solaris Secure Shell is a fork of OpenSSH it means that the very same protocol is used in scp(1) in Solaris. Having said all of that I should have probably named this blog entry How the RCP protocol works but it doesn't look cool, you know. If you have more information about the history of the protocol let me know please.

How it works

I will talk only about scp. As already said, rcp is the same beast with regard to the protocol, it just uses rlogin as a mode of transportation. The synopsis for scp(1) is like this:

scp [options] [user@]host1:]file1 []... [ [user@]host2:]file2

In all cases aside from remote-to-remote scenario the scp command processes command line options and then starts an SSH connection to the remote host. Another scp command is run on the remote side through that connection in either source or sink mode. Source mode reads files and sends them over to the other side, sink mode accepts them. Source and sink modes are triggered using -f (from) and -t (to) options, respectively. These options are for internal usage only and aren't documented. There is also the 3rd hidden option, -d, when the target is expected to be a directory.

So, slightly simplified, the local to remote mode of scp works like this:

The protocol

So, how does the transfer protocol actually works? If you forget about ssh, sshd and the connection between them and concentrate only on interaction between scp in "normal" mode and scp in the sink mode, you can see the scenario like this (if you copied from remote to local the remote scp command would have been run with -f option instead of -t, denoting the source mode):

Another important thing is that scp processes with options -f and -t never run against each other. That means that one of those options is always used on the remote side and local scp process (the one started by the user from the command line) then simulates the other mode because it's also the process that interacts with the user.

The source mode

The protocol is a mixture of text and binary data that form protocol messages. For example, when the regular file is about to be sent (= source mode), the type of the message, mode, length and filename are provided in plain text, followed by a new line. The file data itself follows; more on this later. The message can look like this:

C0644 299 group

There might be more protocol text messages before the binary data transfer actually begins. The scp in source mode (= data producer) always waits for a reply before the next protocol line is sent. After the last protocol message was sent, the producer sends a zero byte to notify scp in sink mode about beginning of the actual data transfer. A confirmation zero byte is sent by the sink mode scp process after the last byte of a file was read on the other side.

The sink mode

Every message and every finished file data transfer from the provider must be confirmed by the scp process that runs in a sink mode (= data consumer). The consumer can reply in 3 different messages; binary 0 (OK), 1 (warning) or 2 (fatal error; will end the connection). Messages 1 and 2 can be followed by a text message to be printed on the other side, followed by a new line character. The new line character is mandatory whether the text is empty or not.

List of protocol messages

Cmmmm <length> <filename>
a single file copy, mmmmm is mode. Example: C0644 299 group
Dmmmm <length> <dirname>
start of recursive directory copy. Length is ignored but must be present. Example: D0755 0 docs
E
end of directory (D-E pairs can be nested; that's why we can copy recursively)
T<mtime> 0 <atime> 0
modification and access times when -p options is used (I guess you know why it doesn't make sense to transfer ctime). Times are in seconds, since 00:00:00 UTC, Jan. 1, 1970. Two zeroes are present there in case there is any need to use microseconds in the future. This message was not present in original rcp implementation. Example: T1183828267 0 1183828267 0

After the messages the raw data is transfered. The consumer reads exactly that much data as specified in the length field. D and T message must be specified before any other messages. This is because otherwise it couldn't be clear whether those lines are part of the protocol or part of the data transfer. From the way how the protocol works we can induce that:

 

  • after C message the data is expected (unless the file is empty)
  • after D message either C or E is expected. This means that it's correct to copy an empty directory providing that user used -r option.

Maximum file size and file integrity protection

Maximum file size depends on the SCP software and the systems (and filesystems) where the software is used on. Given the fact that the file size is transferred as text the only limitation may happen in the server or the client. OpenSSH (so SunSSH as well) uses long long int type to process the file size. This type must be able to hold at least 2\^63. That's a huge number since 2\^40 is 1000GB (a thousand GB), for example. This means that practically there is no file size limit in OpenSSH as such. Do not forget that on FAT32, for example, you can not have a file greater than 4GB.

Strong integrity protection is provided by the underlying SSH protocol. Some of that has been discussed in my blog entry on some SSH error messages, full specification of the protocol can be found in RFC 43253, The Secure Shell (SSH) Transport Layer Protocol.

Examples

Now it's time to have some fun. The protocol description might not be that describing like a few simple examples.

  1. single file copy to the remote sidelet's have a file test, containing string "hello" and we want to copy it over SCP protocol to /tmp directory.
    $ rm -f /tmp/test
    <b>$ { echo C0644 6 test; printf "hello\\n"; } | scp -t /tmp</b>
    test                 100% |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*| 6       00:00    
    $ cat /tmp/test 
    hello

    Nice, isn't it? I used printf so that it's clear why we used 6 for the file length. Now something with a directory copy.

  2. recursive directory copy to the remote sidelet's have the file test in a directory testdir. Now we want to recursively copy the whole directory to /tmpon the "other side".
    $ rm -rf /tmp/testdir
    <b>$ { echo D0755 0 testdir; echo C0644 6 test;
        printf "hello\\n"; echo E; } | scp -rt /tmp</b>
    test                 100% |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*| 6       00:00    
    $ cat /tmp/testdir/test 
    hello

    Note that we had to use -r option because the directory copy was involved.

  3. copy the directory from the remote sidenow the scp program in the pipe will represent the remote side, the producer of the data. As said in the protocol section, the consumer (we) must reply to every protocol message and also to the finished data transfer. Note that this will not create any directory or file since generated protocol messages and data sent are just printed to your terminal - no one reads or interprets them, we just want to see scp's output in the source mode:
    $ cd /tmp
    $ rm -rf testdir
    $ mkdir testdir
    $ echo hello &gt; testdir/test
    <b>$ printf '\\000\\000\\000\\000\\000\\000' | scp -qprf testdir</b>
    T1183832947 0 1183833773 0
    D0700 0 testdir
    T1183833773 0 1183833762 0
    C0600 6 test
    hello
    E

    A little explanation - you don't see data progress bar because of -q option. You see time protocol messages because we asked for them via -p option. And -f means that scp was the producer of the data. Also note that we had to use six '\\0' characters - the first for initializing the transfer, 4 to confirm the messages and 1 for the data transfer. Is that correct? Not exactly because we didn't acknowledged the final E message:

    $ echo $?
    1

    and that's why scp returned failure. If we use 7 binary zeroes everything is fine then:

    <b>$ printf '\\000\\000\\000\\000\\000\\000\\000' | scp -qprf testdir</b>
    T1183832947 0 1183833956 0
    D0700 0 testdir
    T1183833773 0 1183833956 0
    C0600 6 test
    hello
    E
    $ echo $?
    0
  4. sending an error messageThe example shows that scp will exit when we reply with binary 2. You can see that even when we send a couple of zeroes after that the scp command doesn't accept them anymore.
    <b>$ printf '\\000\\000\\002\\n\\000\\000' | scp -qprf testdir</b>
    T1183895689 0 1183899084 0
    D0700 0 testdir

Running scp with talkative shell profiles on the remote side?

People sometimes hit problems with scp while SSH connections continue to work. This is usually a problem with adding echo/printf commands to their shell profile. See two examples.

scp just hangs after the password is entered when I try to copy to the remote side

For example, this can happen if you add this to your shell profile on the remote system:

echo ""

Why it just hangs? That comes from the way how scp in source mode waits for the confirmation of the first protocol message. If it's not binary 0, it expects that it's a notification of a remote problem and waits for more characters to form an error message until the new line arrives. Since you didn't print another new line after the first one, your local scp just stays in a loop, blocked on read(2). In the meantime, after the shell profile was processed on the remote side, scp in sink mode was started, which also blocks on read(2), waiting for a binary zero denoting the start of the data transfer. So, both scp's are blocked on reading, effectively causing a deadlock. In summary, the problems was caused because your remote shell through its profile output "joined" the protocol conversation.

scp just executes my profile and exits if I copy to the remote side

...meaning that scp just prints the 1st message that is printed from user's shell profile and exits. That's because you added for example this into your shell profile:

$ echo 'echo "hi there!"' >> .bashrc

and then run the scp command:

$ cp /etc/passwd localhost:/tmp
hi there!
$ echo $?
1

This is a very similar problem to the one already mentioned. Since the first character received wasn't binary 0 (but character 'h') it assumes a problem, reads up to the next new line character, prints that out as an error message and exits.

There is an easy fix for those problems - just print what you want when you have a terminal, like this:

tty -s && echo "hi there!"

I see protocol error: unexpected <newline> message and scp exits

Again, similar to the 1st problem, but you are copying from the remote side. What happened? Your local scp, the data consumer, waits for the protocol message from the producer. However, it gets an empty line immediately followed by a new line character which is a violation of the protocol and your local scp then bails out. If you print more characters in your remote shell profile it is considered an error message (unless it starts with a valid protocol character in which situation the message finally printed before it fails will be even more confusing) and the whole message up to the new line character is printed and scp exits then. Example if I add printf "XXXX" to my profile (remember, printf(1) doesn't automatically add a new line) - the whole output up to the first protocol message ending with the new line is considered an error message:

$ scp localhost:/etc/passwd .
Password: 
XXXXC0644 1135 passwd
$ echo $?
1

And if you mess up with a valid message, for example D with printing this from your remote shell profile: printf "D":

$ scp localhost:/etc/passwd .
Password: 
protocol error: bad mode
$ echo $?
1

Moral of this? Always check the return code of scp.

Extensibility of the protocol

The protocol is very simple so the question is how extensible can it be. What if we wanted to transfer ACL information as well? The problem is how to extend it in a backward compatible way. Maybe I'm missing something but I doubt it is possible in an easy way. The problem is that you can't extend existing messages. See what happens when we try to add "123" at the end of T message:

$ { echo T1183832947 0 1183833773 0 123;
    echo D0755 0 testdir; echo E; } | scp -rt /tmp
scp: protocol error: atime.usec not delimited

and similary with C message:

$ { echo D0755 0 testdir; echo C0644 6 test 123;
    printf "hello\\n"; echo E; } | scp -rqt /tmp
$ ls -1 /tmp/testdir/
test 123

You can't add a new message because the scp command refuses it right away:

$ { echo X 1 a; echo D0755 0 testdir; echo C0644 6 test;
    printf "hello\\n"; echo E; } | scp -rt /tmp
scp: X 1 a
$ echo $?
1

One possible way (are there other ways?) I see is that you could start the scp command on the other side with a new option meaning some specific extensions can be used. If it fails it probably means that the scp command is from another vendor and your scp will run it again in a compatible mode. However, I'm not sure this is worth the hassle. Some vendors use SFTP protocol even for scp(1) and that is what we are thinking about, too. I think it might be possible just to exec sftp(1) in non-interactive mode after converting some options. The sftp command can already download files using command line and there is 6474758 for upload.

Remote to remote mode

A common question is why remote to remote copy doesn't work with password or keyboard-interactive authentication. It's not a bug, it's a feature. It could be done in the code but most important reason why not to might be that you wouldn't want to reveal your hostB password to hostA because this is how it works - you local scp runs ssh to hostA with remote command like this: "scp fileX hostB:...".

Recently we updated the scp man page with this section:

Generally, use of scp with password or keyboard-interactive
authentication method and two remote hosts does not work. It does
work with either the pubkey, hostbased or gssapi-keyex
authentication method. For the pubkey authentication method,
either private keys not protected by a passphrase, or an explicit
ssh agent forwarding have to be used. The gssapi-keyex
authentication method works with the kerberos_v5 GSS-API
mechanism, but only if the GSSAPIDelegateCredentials option is
enabled.

Efficiency

You can understand now from the way how scp protocol works why copying many small files over a high latency link might take so long in comparison to tarring the whole directory and pipe it through ssh. Those confirmation messages after every protocol message and data transfer is a big overhead. So the next time, you can do something like this and you will see how faster it can be:

tar cfv - testdir | ssh user@host 'cd /tmp; tar xfv -'

Conclusion

That's all. I would just conclude that the rcp/scp protocol is a very simple file transport protocol that appeared when the rcp command started to be shipped with 4.2BSD. It wasn't designed with extensibility in mind and SFTP protocol might replace it in the future in many scp implementations.

=======================================分割线完=====================

欢迎大家访问我的个人独立博客: http://www.byneil.com

 

 

byNeil
byNeil.com

原文来自 Blog by Neil, post 收藏 scp (Secure copy)协议 转载请注明出处。本站保留一切权力

我眼中的SAML (Security Assertion Markup Language)

提到SAML (Security Assertion Markup Language), 很多人都会联想到单点登录SSO。那么Saml到底是什么,它跟sso到底有什么联系?这里给大家分享一下我在读完了saml差不多全部规范之后的一些心得。希望给saml入门者一些帮助。

Saml是什么

首先,saml是一种xml格式的语言。 翻译过来大概叫 安全断言(标记)语言。  这里有两个点: 第一是“安全”, 第二是“断言(assertion)”。  用人话翻译saml就是 用安全的方式表达断言一种语言。

先看它的核心概念“断言”。  断言是什么?  就是做出判断的语言。比如一句话: 小明是超级管理员。 这就是一个断言。再来一个例子:小红没有权限读取根目录。这也是一个断言。  这种“做出判断的语句”我们在很多场合都需要用到。  比如你在网上尝试登陆一个服务的时候, 这个服务需要知道你是不是合法的用户。 这个时候如果你能提供一个“安全,可靠,可信任”的断言:“小明有权登陆XX服务”, 那么这个服务就知道你合法了, 于是就能为你提供服务了。  这个例子比较抽象,但基本上能表达断言在实际用例中的作用了。 实际上saml的大部分用例就在于证明你是谁,你拥有什么权限等等了。 saml中大部分主要内容也都是类似于:你是谁, 你有什么。。等等这些简单的语句。 详细内容后面会介绍。

接下来第二个概念就是“安全”了。  你能提供一个断言, 别人能不能假冒你提供一个断言从而骗取服务端的信任呢? 另外服务端为什么会信任你给的断言呢? 这就涉及到安全的问题了。为了防止断言被假冒,篡改。saml中加入了安全措施。 当然现今能抵御假冒,篡改,重放攻击的利器就是公钥-私钥系统了。  通过给断言加上签名和加密,再结合数字证书系统就确保了saml不受攻击。

 

在很多sso的场合中, 都支持saml登陆。 这就是saml最多的一个应用场景。  作用相当于大家熟知的OpenID,和Oauth等等。

 

好了,说完了大体的概念,就来程序员最喜欢的硬菜了。

 

从技术的角度看saml。

saml迄今为止有两个广泛应用的标准, Saml 1.1 和Saml 2.0

为了尝鲜,大家先看两个saml的例子, 看个样子即可,不用阅读内容,给你1分钟, 看完赶紧回来接着看这里哦:

http://en.wikipedia.org/wiki/SAML_1.1

http://en.wikipedia.org/wiki/SAML_2.0

 

恩,很好, 你已经知道saml大概长什么样了。   saml1.1和saml2.0 是同一个标准的两个版本, 他们在逻辑概念或者对象结构上大致相当, 只是在一些细节上有所差异。 这两个版本不兼容。 另外1.1比2.0要简单许多。  所以下面在讲逻辑结构的时候一般不区分这两个版本,除非特别说明的地方。

我猜你一定喜欢下面这种图:

这张图取自:  https://www.oasis-open.org/committees/download.php/11511/sstc-saml-tech-overview-2.0-draft-03.pdf

这是saml2.0的一个极其简单的应用场景.  如果你不嫌烦的话,我来解释一下这个图:

图上共有三个角色, 1,SP, 服务提供者。 2, Idp,认证用户并生成断言。 3,就是用户你了, client。

首先, 你(client)是idp的注册用户, 它有你的用户名和密码,它可以认证你就是你。 其次, SP和Idp两者会被各自的域管理员设置为相互信任对方。并且双方都持有对方的公钥。这是配置好的。第三,有一天,你需要访问sp提供的某个服务,但是sp并不认识你,也没有你的用户名和密码因此不能认证你。 于是就发生了上图所示的8个步骤:

1. 你去访问sp的某个受保护资源,比如浏览器打开: http://www.apc.com/resource1.aspx.

2. sp发现你是新来的,没有认证信息。当然不能给你这个页面内容了。 他就会生成一个 saml的认证请求数据包(当然是saml格式的)。把这个请求放在一个html的form的一个隐藏的域中,把这个html form返回给你。 这个form后面有一句javascript自动提交这个form。 二而form的action地址就是 提前配置好的 idp上的一个地址。

saml认证请求的数据包可能是这个样子的:

==========

<samlp:AuthnRequest
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="aaf23196-1773-2113-474a-fe114412ab72"
    Version="2.0"
    IssueInstant="2004-12-05T09:21:59"
    AssertionConsumerServiceIndex="0"
    AttributeConsumingServiceIndex="0">
    <saml:Issuer>https://sp.example.com/SAML2</saml:Issuer>
    <samlp:NameIDPolicy
      AllowCreate="true"
      Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
  </samlp:AuthnRequest>

==========

而返回的html from内容大概设这个样子的:它包含了上面的数据包作为其中一个hidden的值。

=============================

<form method="post" action="https://idp.example.org/SAML2/SSO/POST" ...>
    <input type="hidden" name="SAMLRequest" value="<samlp:AuthnRequest>.......... </samlp:authnreques>" />
    ... other input parameter....
    <input type="submit" value="Submit" />

</form>

<javascript>
document.form[0].submit();// 后面紧跟一句类似这样的提交代码.
</javascript>

=============================

这些代码一部分是复制过来的, 有些是我现写的, 大家领会意思即可,不要在意那些细节。

 

3. 上面的form会被javascript自动提交到idp的某个地址。

4. idp也需要认证你, 于是返回给你一个认证的页面, 可能使用用户名密码认证,也可以使用ntlm认证等等一切可以认证你的方式。 因为idp保存有你的用户名和密码。

5. 同上一步,也是认证你的一个过程。

6. idp在认证你之后。觉得你合法, 于是就为你生成一些断言, 证明你是谁,你有什么权限等等。 并用自己的私钥签名。 然后包装成一个response格式,放在form里返回给你。

断言的格式大概如下:

=============

<saml:Assertion
   xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   ID="b07b804c-7c29-ea16-7300-4f3d6f7928ac"
   Version="2.0"
   IssueInstant="2004-12-05T09:22:05">
   <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
   <ds:Signature
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
   <saml:Subject>
..........
   </saml:Subject>
   <saml:Conditions
.........
   </saml:Conditions>
   <saml:AuthnStatement
     AuthnInstant="2004-12-05T09:22:00"
     SessionIndex="b07b804c-7c29-ea16-7300-4f3d6f7928ac">
     <saml:AuthnContext>
       <saml:AuthnContextClassRef>
         urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
      </saml:AuthnContextClassRef>
     </saml:AuthnContext>
   </saml:AuthnStatement>
   <saml:AttributeStatement>
     <saml:Attribute
       xmlns:x500="urn:oasis:names:tc:SAML:2.0:profiles:attribute:X500"
       x500:Encoding="LDAP"
       NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
       Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
       FriendlyName="eduPersonAffiliation">
       <saml:AttributeValue
         xsi:type="xs:string">member</saml:AttributeValue>
       <saml:AttributeValue
         xsi:type="xs:string">staff</saml:AttributeValue>
     </saml:Attribute>
   </saml:AttributeStatement>
 </saml:Assertion>

=============

其中authnstatement认证语句表示你认证成功了。subject表示你是谁。而attributestatement表示你有哪些属性。 还有一个授权语句上面例子中没有。

Response语句大概如下:

============================

 <samlp:Response
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="identifier_2"
    InResponseTo="identifier_1"
    Version="2.0"
    IssueInstant="2004-12-05T09:22:05"
    Destination="https://sp.example.com/SAML2/SSO/POST">
    <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
    <samlp:Status>
      <samlp:StatusCode
        Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
    </samlp:Status>
    <saml:Assertion
      xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
      ID="identifier_3"
      Version="2.0"
      IssueInstant="2004-12-05T09:22:05">
      <saml:Issuer>https://idp.example.org/SAML2</saml:Issuer>
      <!-- a POSTed assertion MUST be signed -->
     ....................
    </saml:Assertion>
  </samlp:Response>

============================

正如上面第2步一样,它也会把response包装在一个form里面返回给你,并自动提交给 sp的某个地址。

===========

 <form method="post" action="https://sp.example.com/SAML2/SSO/POST" ...>
    <input type="hidden" name="SAMLResponse" value="<samlp:Response>.........</samlp:respons>" />
    <input type="hidden" name="RelayState" value="''token''" />
    ...
    <input type="submit" value="Submit" />
  </form>
<javascript>
document.form[0].submit();// 后面紧跟一句类似这样的提交代码.
</javascript>

===========

 

7. 于是就到了第7步, 这个form被javascript自动提交到sp了。

8. sp读到form提交上来的 断言。 并通过idp的公钥验证了断言的签名。 于是信任了断言。 知道你是idp的合法用户了。 所以就最终给你返回了你最初请求的页面了。  http://www.apc.com/resource1.aspx.

 

好了一个最简单的saml用例就讲完了。 你可以看到其中几乎所有的步骤都可以自动完成,用户在第一步访问资源之后,就看到浏览器再自动跳转,自己不需要操作什么,几秒钟过后,资源就访问成功了。

 

到这里, 相信saml在你心目中的形象一定跟家立体了。  如果你还有兴趣就继续往下看吧.

上面是“远观”, 下面我们走近。

先看saml标准的结构:

 

此图出自: https://www.oasis-open.org/committees/download.php/11511/sstc-saml-tech-overview-2.0-draft-03.pdf

saml标准从内到外 可以分为上图的4个层次:

1. Assertion。 断言。 规定了断言的xml结构, 例如:

==============

<saml:Assertion>

..............

</saml:Assertion?

==============

它规定了,这个assertion节点到底该怎么写, 其实就是这个节点的schema。 按照这个规定写出来的assertion别人才能认识。

2. Protocols。协议。它规定了如何请求(samlrequest)和回复(samlresponse )saml消息,其中当然包含assertion的消息。比如:

===============

<samlp:AuthnRequest>

............

</samlp:AuthnRequest>

 

还有:

<samlp:Response>

..............

</samlp:Response>

 

===============

它规定了怎么发送这些请求消息,和回复消息的结构。 这样sp,idp之间才能通信。

 

3. 绑定。  上面两点都是规定了静态结构。 具体这些消息怎么发送呢。 就是用什么协议来承载这些smal消息呢。就是绑定出马了。 最常用的就是http或者soap消息。  把上面的saml消息通过http或者soap消息来传输。 这样sp和idp就能通信了。  saml1.1只支持 http的soap绑定。 而saml2.0支持更多的绑定。 有兴趣自己阅读标准。   这里需要强调的是, 你可能已经想到了,那就是这个绑定其实不重要。 只要saml消息本身是完整的可靠的,下层用什么协议传输不重要。  对。 saml标准规定的绑定只是一种标准实现。  saml的消息可以绑定到任何协议上, 只要sp和idp实现协商好就行了。  这里面应用最广泛的恐怕要算saml的wss绑定了。 用在微软的一系列产品里面。 包括sharepoint online的登陆授权, windows azure登陆,以及windows store的登陆授权等等。  微软自己在ws-trust和ws-secure协议上传输了saml消息。  这恐怕是saml标准以外用的最多的绑定了。

4. Profile, 这个单词我实在不知道翻译成啥好,所以就写原文把。 我个人喜欢把它叫做一套配置,或者叫解决方案。 它规定了某些场景下一整套saml认证的细节和步骤。 比如, 它规定了比较著名的SSO方案。 就是如何用saml实现sso的一整套配置和详细步骤。  概念就是这样。  同上, 上面的绑定都不确定,所以这个profile就更自由了。 你可以使用任何自己定义的profile,只要你们自己协商好就行了。

 

恩好吧, 先到这吧。大体结构已经出来了。 我并不想详细介绍每个xml节点怎么写。大家可以参考标准规范。 看了这篇随笔,相信如果万一哪天你要做saml, 你也不会害怕了。 后续我可能会再分享一下有趣或者有坑的地方。 欢迎大家访问我的个人独立博客交流学习: http://byNeil.com

附上saml协议标准地址:

https://www.oasis-open.org/committees/download.php/3406/oasis-sstc-saml-core-1.1.pdf

http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf
byNeil
byNeil.com

原文来自 Blog by Neil, post 我眼中的SAML (Security Assertion Markup Language) 转载请注明出处。本站保留一切权力