0%

问题

来自“http://localhost:8080/login.html”的资源已被阻止,因为 MIME 类型(“text/html”)不匹配(X-Content-Type-Options: nosniff)

解决方案

有网友是这样说的 :

我想知道该文件是否根本不存在,而 Joomla 会返回默认的 404 响应?

然后在浏览器里查看网络资源,果然没有,应该是被Spring Security拦截掉了,然后Spring Security返回的不是网页期待的格式,所有报错。
在Spring SecurityConfig中放开css权限就可以了。

参考链接

  1. X-Content-Type-Options
  2. 自定义文件的位置错误…

应该注意的语法问题

问题1:

jpa映射错误

解决方案:

类中关联表属性写错

问题2:

程序获取到的值为空

解决方案:

获取不到相关属性时,首先考虑是否传值成功,然而这里的问题在于属性的载体类本身就有问题,就算参数正确,也获取不到值,需要考虑是不是类中属性名称写错,private、static等写错,或者类中的注解不正确。

基于XML的配置

1
2
3
4
5
6
7
8
<beans>
<import resource="resource.xml"/>
<bean id="userService" class="com.example.***.UserService" init-method="init" destory-method="destory">
</bean>
<bean id="message" class="java.lang.String">
<constructctor-arg index="0" value="test"></constructctor-arg>
</bean>
</beans>

基于注解的配置

1.使用注解声明Bean

Spring提供了四个注解,这些注解与xml定义Bean的效果一致,将组件交给Spring容器管理。组件的名称默认是类名(首字母变小写),可自定义

  • @Component
  • @Controller
  • @Service
  • @Repository

2.配置扫描包的路径

1
2
3
4
<context:component-scan bean-package="com.example.spring">
<context:include-filter type="regex" expression="com.example.spring.*"></context:include-filter>
<context:exclude-filter type="aspectj" expression="com.example.spring"></context:exclude-filter>
</context:component-scan>

基于JAVA类的配置

1.使用@Configuration注解
2.使用@Bean注解

参考链接

1.Spring Bean定义的三种方式

问题

Gitment不显示在界面上的问题,只要项目公开就一定有隐私泄露的风险

解决方案

xx.md页面可直接嵌入HTML代码,好像答非所问233

参考链接

1.Gitment:使用 GitHub Issues 搭建评论系统

问题出现

为了给网站添加搜索功能,网上教程只需要3步:

1.安装插件

1
npm install hexo-generator-searchdb --save

2.修改站点配置文件

1
2
3
4
5
search:
path: search.xml
field: post
format: html
limit: 10000

3.修改主题配置文件

1
2
local_search:
enable: true

解决方案

由于是需要支持搜索的主题才能启用搜索,所以原先的百度efe主题只能弃用,Clonenext主题。
配置好后,运行

1
hexo clean & hexo g & s

点击搜索后一直在载入,网上说可能资源文件被浏览器插件拦截了或第一次加载比较慢,然而本地看了一下,都不是也不能解决问题。
发现控制器里提示search.html 404,查看配置文件发现path: search.xml错写成了path: search.html,由此问题解决

参考链接

1.hexo 搜索功能

Swagger出现404错误

开始学习使用Swagger,然而发现按照教程的步骤写的实例项目有时候可以正常实现功能,有时候却不可以,问题到底出现在什么地方呢?

解决方案

仔细比对了可以正常运行和不能正常运行的项目,发现唯一的区别就是pom.xml中的依赖版本不同,一个是2.x版本,一个是3.0.0,改成2.x后正常运行。
网上搜索了以下swagger3与之前的swagger2使用的方法并不相同,连API的访问路径也不相同,而我看的教程是2.x版的,使用的是3.x,学习教程要注意版本号,新版本的使用要以官方介绍为准。

参考链接

1.升级使用SpringFox的swagger-ui 3.0.0版本
2.Spring Boot整合Swagger2构建RESTful API

RBAC是什么

RBAC模型(Role-Based Access Control:基于角色的访问控制)

1.概述

RBAC认为授权实际上就是Who、What、How三元组之间的关系,也就是Who对What进行How的操作,即“主体”对“客体”的操作

  • Who:是权限的拥有者或主体(如User,Role)
  • What:是操作或对象(operation,object)
  • How:具体的权限(Privilege,正向授权和负向授权)

2.RBAC的组成

在RBAC的模型里,有3个基础组成部分,分别是:用户、角色和权限。
RBAC通过定义角色的权限,并对用户授予某个角色从而控制用户的权限,实现用户和权限的逻辑分离(区别于ACL模型
它们之间的关系如下图所示:
RBAC关系图

3.RBAC支持的安全原则

  • 最小权限原则:RBAC可以将角色配置成其完成任务所需的最小的权限集合
  • 责任分离原则:可以通过调用相互独立互斥的角色共同完成敏感的任务,例如要求一个记账员和财务管理员共同参与统一过账操作
  • 数据抽象原则:可以通过权限的抽象来体现,例如财务操作用借款、存款等抽象权限,而不是使用典型的读、写等执行权限

4.RBAC的优缺点

  • 优点:
    • 简化用户和权限的关系
    • 易于扩展维护
  • 缺点:
    • RBAC模型没有提供操作顺序的控制机制,这一缺陷使得RBAC模型很难适合那些对操作次序有严格要求的系统

RBAC分类

分为4类:RBAC0RBAC1RBAC2RBAC3

  • RBAC0

    RBAC0是最简单、最原始的事项方式,也是其他RBAC模型的基础
    RBAC0
    在这个模型中,我们把权限赋予角色,再把角色赋予用户。用户和角色,角色和权限都是多对多的关系,用户拥有的权限等于他所有的角色持有权限之和。

  • RBAC1

    RBAC1是基于RBAC0的模型,引入了角色间的继承关系,即角色上有了上下级的区别
    RBAC1
    角色间的继承关系可分为一般继承关系和受限继承关系。一般继承关系仅要求角色继承关系是一个绝对偏序关系,允许角色间的多继承。
    而受限继承关系则进一步要求角色继承关系是一个树结构,实现角色间的单继承。
    这种模型适合于角色之间层次分明的业务,可以给角色分组分层。

  • RBAC2

    RBAC2是基于RBAC0模型的基础上,进行了角色的访问控制
    RBAC2的角色限制具体分为两类:静态职责分离SSD(Static Separation of Duty),动态职责分离DSD(Dynamic Separation of Duty)
    RBAC2
    RBAC2中的一个基本限制是互斥角色的限制,互斥角色是指各自权限可以互相制约的两个角色。对于这类角色一个用户在某一次的活动中只能被分配其中的一个角色,不能同事获取两个角色的使用权
    该模型有以下几种约束:

    • 互斥角色:同一用户只能分配到一组互斥角色集合中至多一个角色,支持责任分离的原则。互斥角色是指各自权限互相制约的两个角色。对于这类角色一个用户在某一次活动中只能被分配到其中的一个角色,不能同时获得两个角色的使用权。举个栗子:在审计活动中,一个角色不能同时被指派会计角色和审计员角色。
    • 基数约束:一个角色被分配的用户数量受限;一个用户可拥有的角色数目受限;同样一个角色对应的访问权限数目也应受限,以控制高级权限在系统中的分配。例如公司的领导人是有限的。
    • 先决条件角色:可以分配角色给用户仅当该用户已经是另一角色的成员;对应的可以分配访问权限给角色,仅当该角色已经拥有另一种访问权限。要想获得较高的权限,首先拥有低一级的权限。就像我们生活中,国家主席是从副主席中选举的一样。
    • 运行时互斥:例如,允许一个用户具有两个角色的成员资格,但在运行中不可同时激活这两个角色。
  • RBAC3

    RBAC3=RBAC1+RBAC2,所以RBAC3中既有角色分层,也包括可以增加各种限制

如何设计RBAC

1.RBAC的功能模块
RBAC的功能模块

2.RBAC的执行流程
RBAC的执行流程

3.RBAC的数据库设计
RBAC的数据库设计

参考链接

1.RBAC权限系统分析、设计与实现
2.RBAC权限管理模型:基本模型及角色模型解析及举例
3.RBAC介绍(权限)

什么是JWT

JWT(Json web token),用为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。特别适用于分布式站点的单点登录场景。
JWT的声明一般被用来在用户和服务器之间传递被认证的用户身份信息,也可以增加一些额外的其他业务逻辑所必的声明信息。
该token也可直接被用于认证,也可被加密

为什么要用JWT

  • 基于Session的认证难以扩展
  • 基于Session认证的记录被保存在服务器中,随着认证用户的增多,服务端的开销会明显增大
  • 基于Cookie的认证容易受到CSRF攻击

    如何使用JWT

    基于Token的鉴权机制类似于http协议,也是无状态的,它不需要在服务器去保留用户的认证信息或会话信息。

    流程是这样的

    • 用户使用用户名、密码来请求服务器
    • 服务器验证用户信息
    • 服务器通过验证发送给用户一个token
    • 客户端存储token,每次请求时附带token
    • 服务器验证token的值,并返回数据

Tips:token的加密方式使验证不需要像上篇介绍的防范web攻击而每次请求最好带上随机字符

JWT长什么样

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT是由三段信息构成的,用.连接。

包含两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法
    1
    2
    3
    4
    {
    'typ': 'JWT',
    'alg': 'HS256'
    }
    然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分
    1
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

    payload

    载荷就是存放有效信息的地方,包含三个部分:
  • 标准中注册的声明
  • 公开的声明
  • 私有的声明

标准中注册的声明(建议但不强制使用)

  • iss:jwt签发者
  • sub:jwt所面向的用户
  • aud:接收jwt的一方
  • exp:jwt的过期时间,这个过期时间必须大于签发时间
  • nbf:定义在什么时间之前,该jwt都是不可用的
  • iat:jwt的签发时间
  • jti:jwt的唯一身份标识,主要用来作为一次性的token,从而回避重放攻击

公有的声明:
可以添加任何信息一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密

私有的声明:
是提供者和消费真所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归为类明文信息

定义一个payload:

1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

然后将其进行base64加密,得到jwt的第二部分

1
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header(base64后的)
  • payload(base64后的)
  • secret
    这个部分需要base64加密后的header和base64加密后的payload,使用.连接组成字符串,然后通过header中声明的加密方式进行加盐secret组合加密,就构成了jwt的第三部分
1
2
3
4
// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

最终可连接为最终的jwt

1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

Tips:secret是在服务器端的,jwt的签发生成也是在服务器端,secret是服务器端的私钥,用于进行jwt的签发和验证,所以任何场景都不应该把secret泄露出去

#应用
一般在请求头里加入Authorization,并加上Bearer标注:

1
2
3
4
5
6
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})

转载自:
1.什么是JWT

序言

以下内容为个人学习总结,不保证完全信息严谨可靠

背景

由于Http协议是无状态协议,也就是说当用户通过浏览器像服务器发送请求时,服务器无法判断用户身份,所以为了确定请求的合法性,浏览器请求时必须提交额外的数据,比如cookie等

产生的问题

为了窃取用户数据就产生了各种各样的非法请求,总的来说分为两类:

  • 1.合法用户(受害者)提交非法请求(XSS跨站脚本攻击,点击劫持/UI覆盖攻击)
  • 2.非法用户提交合法请求(CSRF跨站请求伪造)

    XSS跨站脚本攻击

    名称

    跨站脚本攻击(Cross Site Scripting),为了不和层叠样式表(Cascading Style Sheets,CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。

    分类

    • ReflectedXSS(基于反射的XSS攻击)
    • StoredXSS(基于存储的XSS攻击)
    • DOM-bases or local XSS(基于DOM或本地的XSS攻击)

      概括

      XSS攻击的本质:利用一切手段在目标用户的浏览器中执行攻击脚本

CSRF攻击

名称

CSRF(Cross-site request forgery),跨站请求伪造,也被称为one cliclk attack/session riding,缩写为:CSRF/XSRF

原理

攻击者盗用用户身份,以合法名义发送请求。

示意图

CSRF攻击思想
从上图可以看出,完成一次CSRF攻击,受害者必须依次完成两个步骤:

  • 1.登录受信任的网站A,并在本地生成Cookie
  • 2.在不登出A的情况下,访问危险网站B

Csrf攻击是源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以保证一个请求来自某个用户的浏览器,但却无法保证该请求是用户批准发送的。

CSRF的防御

主要从服务端和客户端两方面着手,从防御效果来看,服务端防御比较好

服务端CSRF防御

服务端的CSRF方式总的思想就是在客户端页面增加伪随机数

  • Cookie Hashing(所有表单都包含同一个伪随机值)
    • 在表单里增加Hash值,以认证是用户发送的请求
    • 然后在服务器端进行Hash值验证
  • 验证码
    • 每次用户提交都需要在表单中填写一个图片上的随机字符串,这个完全可以解决CSRF
  • One-Time Tokens(不同的表单包含不同的伪随机值)

参考链接

1.关于web安全的三个攻防姿势

2.浅谈CSRF攻击方式

匹配开头和结尾

^表示开头,用$表示结尾

匹配指定范围

  • [123456789]可以匹配[1~9],还有另外一种表示方法[0-9a-fA-F]
    还有一种排除法,即不包含指定范围的字符。[^1-9]

或规则匹配

  • |连接的两个正则规则是或规则,例如AB|CD

使用括号

  • 如果匹配字符串learn javalearn phplearn go,可以这样写learn\\s(java|php|go)

分组匹配

  • 如何正则匹配区号-电话号这个规则,按照前边的介绍完全可以匹配到,但是匹配成功后,如何区分区号和电话号码,分别存入数据库。
    也就是如何提取匹配的子串?
    正确的方法是用(…)先把要提取的规则分组,然后引入java.until.regex包,用Pattern对象匹配,匹配获得一个Matcher对象,如果匹配成功,可以直接从Matcher.group(index)返回子串

非贪婪匹配

  • 给定一个字符串表示的数字,判断该数字末尾0的个数,例如123000末尾3个010010末尾1个0
    我们的思路是这样的:利用分组匹配把字符串分为末尾为0的部分和其余部分,正则表达式可以这样写:(\d+)(0*)
    然而事情并不是我们想象的那样,为0的那部分始终为空,因为(\d+)已经包含匹配后面的0,第二部分规则根本没机会
    所以我们要让(\d+)少匹配,让(0*)尽量多匹配,就必须使用非贪婪规则。
    在规则(\d+)后面加?即可表示非贪婪匹配

反向引用

  • 如果我们要把搜索到的指定字符串按规则替换,比如前后各加一个xxxx
1
2
3
4
5
6
7
public class Main{
public static void main(String[] args){
String s = "the quick brown fox jumps over the lazy dog.";
String r = s.replaceAll("\\s([a-z]{4})\\s","<b>$1</b>");
System.out.println(r);
}
}

上述代码运行的结果就是:

1
the quick brown fox jumps <b>over</b> the <b>lazy</b> dog.

它实际上把任何4字符单词的前后用xxxx括起来

模板引擎

  • 模板引擎是指,定义一个字符串作为模板:
1
Hello,${name}! You are learning ${lang}!

其中${key},也就是被替换的内容,当传入一个
Map<String,String>给模板后,将key替换为value的值
例如,传入Map为:

1
2
3
4
{
"name":"Bob",
"lang":"Java"
}

最终输出结果为:

1
Hello,Bob!You are learning Java!