什么是jwt

什么是JWT

JWT(Json Web Token)以JSON的格式传输网络安全认证消息,以一种轻量级的消息传输格式来确保服务端的安全。而被传输的JSON信息可以被认证和信任,因为它拥有可信的数字签名。

客户端只需要使用凭证在服务器端认证一次,认证成功之后,服务端会给客户端返回一个JWT,客户端未来的请求都可以使用这个JWT来通过服务端的认证,并且不需要再次发送认证信息,比如说用户名和密码。

image-20211218220701216

需要注意的是,JWT中的payload对每个人都是可见的,因此我们不应该放任何敏感信息比如说密码在其中。我们可以加密payload数据,这样可以让它更加安全。然而我们可以确保没有人可以篡改payload中的信息。

shiro的权限管理之访问许可(permission)

1. Apache Shiro中的permission是什么

Shiro 将 Permission 定义为代表某个明确行为或动作的语句。 它是应用程序中原始功能的声明,仅此而已。 权限是安全策略中最低级别的结构,它们仅明确定义应用程序可以做什么,而不会描述谁可以做这些动作。(和subject即认证主体无关)

2. permission体现在哪些地方

  • 打开一个文件

  • 访问/user/list路径下的网页

  • 打印文档

  • 删除某个用户

定义“谁”(用户)被允许做“什么”(权限)是一种以某种方式为用户分配权限的运用,这始终由应用程序的数据模型完成,并且可能因应用程序而异。

例如,权限可以归入一个角色,并且该角色可以与一个或多个用户对象相关联。 或者一些应用程序可以有一个用户组,一个组可以分配一个角色,通过传递关联意味着该组中的所有用户都被隐式授予角色中的权限。

向用户授予权限的方式有多种变化——应用程序根据应用程序要求确定如何对此进行建模。

3. 通配符权限

上面的权限示例中,“打开文件”,“查看‘用户/列表’网页”等都是有效的权限声明。 然而,在计算上解释这些自然语言字符串并确定是否允许用户执行该行为将是非常困难的。因此,为了实现易于处理但仍然可读的权限语句,Shiro 提供了强大而直观的权限语法,我们称之为通配符权限。

3.1 简单应用

假设您想保护对公司打印机的访问,以便某些人可以打印到特定的打印机,而其他人可以查询当前队列中的作业。

一种极其简单的方法是授予用户“queryPrinter”权限。 然后您可以通过调用来检查用户是否具有 queryPrinter 权限:

1
subject.isPermitted("queryPrinter")

这等价于:

1
subject.isPermitted( new WildcardPermission("queryPrinter") )

这还不够,简单权限字符串可能适用于简单的应用程序,但它需要您拥有“printPrinter”、“queryPrinter”、“managePrinter”等权限。您也可以使用通配符授予用户“*”权限(授予此权限) 构造其名称),这意味着它们拥有整个应用程序的所有权限。

但是使用这种方法,不能只说用户拥有“所有打印机权限”。 因此,通配符权限支持多级权限。

3.2 多个部件

通配符权限支持多个级别或部分的概念。 例如,您可以通过授予用户权限来重构前面的简单示例

1
printer:query

本示例中的冒号是一个特殊字符,用于分隔权限字符串中的下一部分。

在此示例中,第一部分是正在操作的域(打印机),第二部分是正在执行的操作(查询)。 上面的其他示例将更改为:

1
2
printer:print
printer:manage

可以使用的部件数量没有限制,因此就可以在您的应用程序中使用它的方式而言,这取决于您的想象力。

3.2.1 多个值

每个部分可以包含多个值。 因此,与其同时授予用户“printer:print”和“printer:query”权限,您还可以简单地授予他们一个权限:

1
printer:print,query

这使他们能够打印和查询打印机。 并且由于他们被授予了这两个操作,您可以检查用户是否有能力通过调用来查询打印机:

1
subject.isPermitted("printer:query")

这将返回 true。

3.2.2 全部的值

如果您想授予用户特定部分的所有值怎么办? 这样做比手动列出每个值更方便。 同样,基于通配符,我们可以做到这一点。 如果打印机域有 3 个可能的操作(查询、打印和管理),则:

1
printer:query,print,manage

可以简化为:

1
printer:*

然后,对“printer:XXX”的任何权限检查都将返回 true。 以这种方式使用通配符比显式列出操作更有效,因为如果稍后向应用程序添加新操作,则无需更新在该部分使用通配符的权限。

最后,还可以在通配符权限字符串的任何部分使用通配符标记。 例如,如果您想授予用户跨所有域(不仅仅是打印机)的“查看”操作,您可以授予以下权限:

1
*:view

然后对“foo:view”的任何权限检查都将返回true。

未完待续:https://shiro.apache.org/permissions.html

使用aliyun的maven仓库初始化gradle

在linux中使用gradle命令行构建程序时,使用国内镜像可以大大加快我们的构建过程,节约我们的时间,下面就如何配置aliyun仓库作为gradle的默认仓库作出说明。

  1. 如果只想对单个项目生效,那么可以在项目的build.gradle中添加如下配置:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    buildscript {
    repositories {
    maven {url 'https://maven.aliyun.com/repository/google/'}
    maven {url 'https://maven.aliyun.com/repository/jcenter/'}
    }
    dependencies {
    classpath: 'com.android.tools.build:gradle:2.2.3'

    }
    }
    allprojects {
    repositories {
    maven { url 'https://maven.aliyun.com/repository/google/' }
    maven { url 'https://maven.aliyun.com/repository/jcenter/'}
    }
    }
  2. 如果是对所有项目生效,那么需要在用户的家目录下面的.gradle目录下创建init.gradle文件,内容如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    allprojects{
    repositories {
    def ALIYUN_REPOSITORY_URL = 'https://maven.aliyun.com/repository/public/'
    def ALIYUN_JCENTER_URL = 'https://maven.aliyun.com/repository/jcenter/'
    def ALIYUN_GOOGLE_URL = 'https://maven.aliyun.com/repository/google/'
    def ALIYUN_GRADLE_PLUGIN_URL = 'https://maven.aliyun.com/repository/gradle-plugin/'
    all { ArtifactRepository repo ->
    if(repo instanceof MavenArtifactRepository){
    def url = repo.url.toString()
    if (url.startsWith('https://repo1.maven.org/maven2/')) {
    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_REPOSITORY_URL."
    remove repo
    }
    if (url.startsWith('https://jcenter.bintray.com/')) {
    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_JCENTER_URL."
    remove repo
    }
    if (url.startsWith('https://dl.google.com/dl/android/maven2/')) {
    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_GOOGLE_URL."
    remove repo
    }
    if (url.startsWith('https://plugins.gradle.org/m2/')) {
    project.logger.lifecycle "Repository ${repo.url} replaced by $ALIYUN_GRADLE_PLUGIN_URL."
    remove repo
    }
    }
    }
    maven { url ALIYUN_REPOSITORY_URL }
    maven { url ALIYUN_JCENTER_URL }
    maven { url ALIYUN_GOOGLE_URL }
    maven { url ALIYUN_GRADLE_PLUGIN_URL }
    }
    }

设计模式学习手册

设计模式的类别

  • 创造性模式(creational)

    创造型模式控制了对象的创建和类的实例化;

  • 结构性模式(structural)

    结构型设计模式控制了类和对象之间的关系

  • 表现型模式(behavioral)

    表现型设计模式控制了对象之间的交流和交互

    设计模式带来的影响范围——确定了解决方案的关注点

  • 对象层面的影响范围——解决对象关系的问题
    作用于运行期间,对象拥有动态的行为
  • 类层面的影响范围——解决类关系的问题
    作用于编译期间,类拥有静态的行为