简介
SSO是单点登录的简称,罕用的SSO的协定有两种,别离是SAML和OAuth2。本文将会介绍两种协定的不同之处,从而让读者对这两种协定有更加深刻的了解。
SAML
SAML的全称是Security Assertion Markup Language, 是由OASIS制订的一套基于XML格局的凋谢规范,用在身份提供者(IdP)和服务提供者 (SP)之间替换身份验证和受权数据。
SAML的一个十分重要的利用就是基于Web的单点登录(SSO)。
在SAML协定中定义了三个角色,别离是principal:代表主体通常示意人类用户。identity provider (IdP)身份提供者和service provider (SP)服务提供者。
IdP的作用就是进行身份认证,并且将用户的认证信息和受权信息传递给服务提供者。
SP的作用就是进行用户认证信息的验证,并且受权用户拜访指定的资源信息。
接下来,咱们通过一个用SAML进行SSO认证的流程图,来剖析一下SAML是怎么工作的。
上图中User Agent就是web浏览器,咱们看一下如果用户想申请Service Provider的资源的时候,SAML协定是怎么解决的。
- 用户通过User Agent申请Service Provider,比方:
http://sp.flydean.com/myresource
SP将会对该资源进行相应的安全检查,如果发现曾经有一个无效的平安上下文的话,SP将会跳过2-7步,间接进入第8步。
- 如果在第一步的时候,SP并没有找到相应的无效平安上下文的话,则会生成对应的SAMLRequest,并将User Agent重定向到IdP:
302 RedirectLocation: https://idp.flydean.com/SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token
RelayState是SP保护的一个状态信息,次要用来避免CSRF攻打。
其中这个SAMLRequest是用Base64编码的<samlp:AuthnRequest>,上面是一个samlp:AuthnRequest的例子:
<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="2020-09-05T09:21:59Z" AssertionConsumerServiceIndex="0" AttributeConsumingServiceIndex="0"> <saml:Issuer>https://sp.flydean.com/SAML2</saml:Issuer> <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/> </samlp:AuthnRequest>
为了平安起见,SAMLRequest还能够应用SP提供的签名key来进行签名。
- User agent将会发送一个get申请到IdP的SSO server :
GET /SAML2/SSO/Redirect?SAMLRequest=request&RelayState=token HTTP/1.1Host: idp.flydean.com
IdP收到这个AuthnRequest申请之后,将会进行平安验证,如果是非法的AuthnRequest,那么将会展现登录界面。
- 用户能够输出用户名明码进行登录。登录胜利之后,IdP将会返回一个XHTML form:
<form method="post" action="https://sp.flydean.com/SAML2/SSO/POST" ...> <input type="hidden" name="SAMLResponse" value="response" /> <input type="hidden" name="RelayState" value="token" /> ... <input type="submit" value="Submit" /> </form>
这个form中蕴含了SAMLResponse信息,SAMLResponse中蕴含了用户相干的信息。
同样的SAMLResponse也是应用Base64进行编码过的<samlp: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="2020-09-05T09:22:05Z" Destination="https://sp.flydean.com/SAML2/SSO/POST"> <saml:Issuer>https://idp.flydean.com/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="2020-09-05T09:22:05Z"> <saml:Issuer>https://idp.flydean.com/SAML2</saml:Issuer> <!-- a POSTed assertion MUST be signed --> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"> 3f7b3dcf-1674-4ecd-92c8-1544f346baf8 </saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData InResponseTo="identifier_1" Recipient="https://sp.flydean.com/SAML2/SSO/POST" NotOnOrAfter="2020-09-05T09:27:05Z"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2020-09-05T09:17:05Z" NotOnOrAfter="2020-09-05T09:27:05Z"> <saml:AudienceRestriction> <saml:Audience>https://sp.flydean.com/SAML2</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2020-09-05T09:22:00Z" SessionIndex="identifier_3"> <saml:AuthnContext> <saml:AuthnContextClassRef> urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport </saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> </samlp:Response>
咱们能够看到samlp:Response中蕴含有saml:Assertion信息。
- user agent 收到XHTML form之后将会提交该form给SP。
- SP中的assertion consumer service将会解决这个申请,创立相干的平安上下文,并将user agent重定向到要拜访的资源页面。
- user agent再次申请SP资源。
- 因为平安上下文曾经创立结束,SP能够间接返回相应的资源,不必再次到IdP进行认证。
咱们能够看到下面的所有的信息替换都是由前端浏览器来实现的,在SP和IdP之间不存在间接的通信。
这种全副由前端来实现信息替换的形式益处就是协定流非常简单,所有的音讯都是简略的GET或者POST申请。
如果为了进步安全性,也能够应用援用音讯。也就是说IdP返回的不是间接的SAML assertion,而是一个SAML assertion的援用。SP收到这个援用之后,能够从后盾再去查问实在的SAML assertion,从而进步了安全性。
SAML的毛病
SAML协定是2005年制订的,在制订协定的时候基本上是针对于web应用程序来说的,然而那时候的web应用程序还是比较简单的,更别提对App的反对。
SAML须要通过HTTP Redect和HTTP POST协定来传递用户信息,并且通常是通过HTML FORM的格局来进行数据的提交的。如果应用程序并不是web利用,比如说是一个手机App利用。
这个手机APP利用的启动链接是 my-photos://authenticate , 然而手机app可能并不能获取到Http POST的body内容。他们只可能通过URL来进行参数的传递。
这就意味着,在手机APP中不可能应用SAML。
当然,要想工作也能够,不过须要进行一些革新。比方通过第三方利用对POST音讯进行解析,而后将解析进去的SAMLRequest以URL参数的模式传递给APP。
另一种办法就是应用OAuth2.
OAuth2
因为Oauth2是在2012年才产生的。所以并没有那么多的应用限度。咱们能够在不同的场合中应用OAuth2。
咱们先来看一下OAuth2中受权的流程图:
一般来说OAuth2中有4个角色。
resource owner: 代表的是资源的所有者,能够通过提供用户名明码或者其余形式来进行受权。通常来是一个人。
resource server:代表的是最终须要拜访到资源的服务器。比方github受权之后获取到的用户信息。
client: 用来代替resource owner来进行交互的客户端。
authorization server: 用来进行受权的服务器,能够生成相应的Access Token。
整个流程是这样的:
Client向resource owner发动一个受权申请,resource owner输出相应的认证信息,将authorization grant返回给client。
client再将获取到的authorization grant申请受权服务器,并返回access token。
client而后就能够拿着这个access token去申请resource server,最初获取到受限资源。
OAuth2的毛病
OAuth2并没有指定Resource Server怎么和Authorization Server进行交互。也没有规定返回用户信息的内容和格局。这些都须要实现方本人去决定。
OAuth2默认是在HTTPS环境下工作的,所以并没有约定信息的加密形式。咱们须要本人去实现。
最初,OAuth2是一个受权协定,而不是认证协定。对于这个问题,其实咱们能够思考应用OpenID Connect协定。因为OpenID Connect就是基于OAuth2实现的,并且增加了认证协定。
OpenID Connect简称为OIDC,已成为Internet上单点登录和身份治理的通用规范。 它在OAuth2上构建了一个身份层,是一个基于OAuth2协定的身份认证标准协议。
OAuth2实际上只做了受权,而OpenID Connect在受权的根底上又加上了认证。
OIDC的长处是:简略的基于JSON的身份令牌(JWT),并且齐全兼容OAuth2协定。
两者的比照
在SAML协定中,SAML token中曾经蕴含了用户身份信息,然而在OAuth2,在拿到token之后,须要额定再做一次对该token的校验。
然而另一方面,OAuth2因为须要再做一次认证,所以能够在 Authorization Server 端对token进行有效解决。
CAS简介
做过SSO的应该都据说过CAS。CAS的全称是Central Authentication Service,是一个企业级的开源的SSO认证框架。
CAS外部集成了CAS1,2,3,SAML1,2,OAuth2,OpenID和OpenID Connect协定,十分的弱小。咱们会在前面的文章中介绍CAS的应用。
本文作者:flydean程序那些事本文链接:http://www.flydean.com/saml-vs-oauth2/
本文起源:flydean的博客
欢送关注我的公众号:「程序那些事」最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!