solr安全认证

前言

本文是根据solr官方文档翻译和改编来的,所以你也在官方文档中看到过,不要惊讶。

安全认证种类

solr带有安全框架,支持用户认证和限制solr资源的使用。solr插件支持三种认证:
1)基础认证(Basic authentication)
仅仅支持solrCloud模式。
2)Kerberos认证
solrCloud认证和独立模式。
3)基础规则认证(rule-based authorization)
仅仅支持solrCloud模式。
在solrCloud模式下,采用在zk中的/security.json文件来支持,在独立模式下,通过 -DauthenticationPlugin=<pluginClassName> 定义插件来支持。

security.json内容如下,包含两段。

{
"authentication" : {
"class": "class.that.implements.authentication"
},
"authorization": {
"class": "class.that.implements.authorization"
}
}

根据配置使用的插件信息,添加其他诸如用户或规则信息,这些信息传递给插件。
下面是更详细的security.json的例子。 在下面的例子中基本认证和规则认证插件被启用,展示如下:

{
"authentication":{
"class":"solr.BasicAuthPlugin",
"credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0=
Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}
},
"authorization":{
"class":"solr.RuleBasedAuthorizationPlugin",
"permissions":[{"name":"security-edit","role":"admin"}]
"user-role":{"solr":"admin"}
}}

上传到Zookeeper

如果要启用solr的认证,需要先传security.json 到zookeeper中,实例如下:

> server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:2181 -cmd put
/security.json 
'{"authentication": {"class": "org.apache.solr.security.KerberosPlugin"}}'

注意:因为solr的认证信息是传到zookeepr上的,所以zookeeper最好也要是认证的。

认证组成

认证插件在solr的请求点做安全认证,一个定制插件通过扩展AuthenticationPlugin类来实现。
一个认证插件由两个部分组成:
1)服务器组件,使用插件里面定义的kerberos、基础规则或其他的认证机制来解释和认证solr的请求。
2)客户端组建,比如一个HttpClientConfigurer,它让solrJ客户端可以以一种服务器端可以理解的安全认证方式去访问solr实例。

启用一个认证

通过前面的security.json来指定认证:

{
"authentication": {
"class": "class.that.implements.authentication",
"other_data" : "..."}
}
  • 这个json文件中所有的内容,都作为map形式传递给solr的安全插件。
  • 如果是独立的solr实例,可以通过-DauthenticationPlugin=<plugin class name> 在启动的时候指定。

基础认证插件

solr可以通过使用基础认证插件来支持基础的认证。

启用基础认证

为使用基础认证,你首先创建个security.json文件,然后保存到zookeeper上。
认证类为基础认证类,用户名和密码也同样需要添加,用户名和密码为sha256的hash。认证授权部分不是基本认证相关的,但是是一个单独的授权插件设计

支持细粒度用户访问控制。例子如下:

{
"authentication":{
"blockUnknown": true,
"class":"solr.BasicAuthPlugin",
"credentials":{"solr":"IV0EHq1OnNrj6gvRCwvFwTrZ1+z1oBbnQdiVC3otuq0=
Ndd7LKvVBAaZIF0QAVi1ekCfAJXr1GGfLtRUXhgrF8c="}
},
"authorization":{
"class":"solr.RuleBasedAuthorizationPlugin",
"permissions":[{"name":"security-edit",
"role":"admin"}],
"user-role":{"solr":"admin"}
}}

通过如下命令上传到zookeeper上去,如下:

server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983 -cmd putfile
/security.json security.json

在文件中几件事情:
1、基础认证和规则认证都启用了。
2、一个用户叫solr、密码为SolrRocks已经被定义了。
3、“blockUnknown:true”标示未认证的请求不能通过。
4、admin这个角色被定义,它有权编辑认证方式。
5、solr永远被定义为admin角色。

注意事项

使用基本身份验证插件时需要记住以下几点。默认情况下,以纯文本形式发送凭据。建议在基本时使用SSL进行通信。
启用了身份验证,如启用SSL的部分所描述的那样。用户访问到security.json写权限可以修改所有权限以及如何分配用户权限。应特别注意只允许获得将安全性编辑给合适的用户。

当然,你的网络应该是安全的。即使启用了基本身份验证,也不应该
不必要暴露Solr外面的世界。

权限属性

每个角色由一个或多个权限组成,这些权限定义了用户被允许执行的操作。 每个权限
由几个定义允许的活动的属性组成。 有一些预定义的权限
不能修改。
这些权限会在security.json中显示。 第一个匹配的权限是
适用于每个用户,因此最严格的权限应该位于列表的顶部。 权限顺序可以
使用授权API的参数进行控制,如下所述。

预定义的权限

有几个预先定义的权限。这些具有固定的默认值,不能修改,
并且不能添加新的属性。要使用这些属性,只需定义一个包含此权限的角色,
然后将用户分配给该角色。
预定义的权限是:

  • security-edit::允许此权限编辑安全配置,即任何更新操作
    通过API修改security.json将被允许。
  • security-read::允许此权限读取安全配置​​,即读取任何操作
    通过API的security.json设置将被允许。
  • schema-edit:允许此权限使用模式API编辑集合的模式。注意
    这允许所有集合的架构编辑权限。如果编辑权限只应用于
    特定的集合,则需要创建自定义权限。
  • schema-read:允许此权限使用模式API读取集合的模式。注意
    这允许所有集合的模式读取权限。如果读取权限只应用于
    特定的集合,则需要创建自定义权限。
    config-edit:允许此权限使用配置API Reque来编辑集合的配置
    st参数API和修改configoverlay.json的其他API。请注意,这允许
    所有集合的配置编辑权限。如果编辑权限只应用于特定
    集合,需要创建自定义权限。
    core-admin-read:读取核心管理API上的操作
    core-admin-edit:可以改变系统状态的核心管理命令。
    config-read:允许此权限使用Config API(请求)读取集合的配置
    est参数API以及修改configoverlay.json的其他API。请注意,这允许
    配置所有集合的读取权限。如果读取权限只应用于特定的
    集合,需要创建自定义权限。
    collection-admin-edit:允许此权限使用集合编辑集合的配置
    API。请注意,这允许所有集合的配置编辑权限。如果只有编辑权限
    应用于特定集合,则需要创建自定义权限。具体来说,
    将允许以下集合API的操作:
    创建
    RELOAD
    SPLITSHARD
    CREATESHARD
    DELETESHARD
    CREATEALIAS
    DELETEALIAS
    删除
    DELETEREPLICA
    ADDREPLICA
    CLUSTERPROP
    迁移
    ADDROLE
    REMOVEROLE
    ADDREPLICAPROP
    DELETEREPLICAPROP
    BALANCESHARDUNIQUE
    REBALANCELEADERS
    collection-admin-read:允许此权限使用集合读取集合的配置
    s API。请注意,这允许所有集合的配置读取权限。如果读取权限应该
    只适用于特定集合,需要创建自定义权限。具体来说,
    将允许以下集合API的操作:
    LIST
    OVERSEERSTATUS
    CLUSTERSTATUS
    REQUESTSTATUS
    更新:允许此权限对任何集合执行任何更新操作。这包括发送
    索引文件(使用更新请求处理程序)。
    阅读:允许此权限对任何集合执行任何读取操作。这包括查询使用
    搜索处理程序(使用请求处理程序),例如/ select,/ get,/ browse,/ tvrh,/ terms,/ cluste
    环,/提升,/导出,/拼写,/集群和/ sql。
    全部:任何请求到Solr。

编辑认证插件的配置

一个认证API准许更改用户ID和密码。API提供了设置用户信息和删除用户的方方法。

API访问点

admin/authentication
这个访问点没有指定集合,所以对整个集群都起作用,如果需要限制特定的集合,可以通过认证规则来做。

添加用户或编辑密码

set-user命令可以让你添加用户或更改他们的密码。举个例子,下面的命令定义了两个用户两个密码

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H
'Content-type:application/json' -d '{
"set-user": {"tom" : "TomIsCool" ,
"harry":"HarrysSecret"}}'

删除用户

删除用户命令准许你删除一个用户,用户密码在删除的时候不用发过去。在下面的例子中,我们删除一个ID为tom和harry的。

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H
'Content-type:application/json' -d '{
"delete-user": ["tom","harry"]}'

设置属性

更改安全文件里面的属性定义如:

curl --user solr:SolrRocks http://localhost:8983/solr/admin/authentication -H
'Content-type:application/json' -d '{
"set-property": {"blockUnknown":false}}'

solrJ中支持基础认证

SolrRequest req ;//create a new request object 
req.setBasicAuthCredentials(userName, password); 
solrClient.request(req);

solr内部认证

有很多来自Solr节点本身的要求。例如:要求监督节点、恢复线程等。这些要求不携带任何级别身份验证凭证因为没有用户发起这些请求。
这意味着solr本身,使用一种特殊的认证机制,各节点间solr节点是一个超级用户由其他solr节点完全信任。

kerberos认证插件

如果在你的网络环境中有kerberos认证,kerberos插件可以用来认证solr集群。这准许solr使用kerberos principal 和keytab文件来认证zookeeper和solr集群。
管理UI和所有客户端(solrJ)将需要一个合法的ticket来使用UI和对solr发送请求。
kerberos认证插件仅仅在solrCloud模式下有用。

带有kerberos认证的solr如何工作

当设置solr使用kerberos时候,一个在KDC中注册认证的服务principal 或者kerberos 用户名的配置是需要的。这个配置定义了服务主体的名称和keytab文件的位置。solr的认证模式是用/security.json这个文件,如果更改这个文件,需要重启整个solr集群。此外认证插件可以通过系统启动参数制定:
-DauthenticationPlugin=org.apache.solr.security.KerberosPlugin.
这个参数可以用在solrClound 或单独模式下,在单独模式下这是唯一的方式。

服务主体和keytab文件

kerberos认证说明:


转自:http://blog.csdn.net/wangyangzhizhou/article/details/51163782
SPNego认证

流程:
①客户端浏览器向web服务器发送http请求。

②服务器返回401状态码,响应头部加上 WWW-Authenticate:Negotiate。

③用户通过浏览器输入用户名向AS请求TGS票证。

④AS生成TGS票证,然后查询用户密码并用此密码加密TGS票证,返回浏览器。

⑤浏览器使用用户密码解密出TGS票证,并向TGS服务发起请求。

⑥TGS服务生成服务票证响应给浏览器。

⑦浏览器将服务票证封装到SPNEGO token中,并发送给web服务器。

⑧服务器解密出用户名及服务票证,将票证发往TGS服务验证。

⑨通过验证,开始通信。

每个solr节点必须在KDC(Key Distribution Center)中注册有一个服务主体。
kerberos插件利用SPNego 进行认证,Spnego模式是一种由微软提出的使用GSS-API接口的认证模式,它扩展了Kerberos协议。
以“HTTP/host1@YOUR_DOMAIN.ORG”为一个服务主体例子:

  • HTTP 表示什么类型的请求被认证。HTTP/ 在服务主体必须是工作在HTTP上的SPNego请求。
  • host1 匹配的solr节点的主机名字。
  • YOUR_DOMAIN.ORG 是组织的kerberos的realm(域)。
    不同的solr节点在相同的主机上,可能有相同的服务主体,因为主机名对它们来说是相同的。
    和服务主体在一起的,每个solr节点需要一个包含一个keytab文件,包含服务主体需要的认证信息。keytab文件包含加密的认证来支持从kerberos中获取kerberos ticket无密码登陆信息。对于每个solr节点来说,keytab文件应该保存在安全地方,且不能被集群中的其他用户共享。
    因为solr集群需要内部通信,每个节点必须可以和其他节点建立kerberos请求。默认情况下,solr使用相同的服务主体和keytab文件作为“client principal”来进行内不能通信。你也许想配置特别的不同的principal客户端,但是这样做是不建议的。

kerberized Zookeeper

设置Kerberos SolrCloud集群时,建议为ZooKeeper启用Kerberos安全性。

在这种设置中,用于通过ZooKeeper验证请求的客户端主体也可以用于节点间通信。 由于Solr使用的Zookeeper客户端负责完成这项工作,因此无需分别续订票证授予票证(TGT)。 为此,可以将单个JAAS配置(应用程序名称为Client)用于Kerberos插件以及Zookeeper客户端。

有关在Kerberos模式下启动ZooKeeper的示例,请参阅下面的ZooKeeper配置部分。

浏览器配置

为了让您的浏览器在启用Kerberos身份验证后访问Solr管理界面,它必须能够与Kerberos身份验证器服务协商以允许您访问。 每种浏览器都支持这种方式,有些(如Chrome)完全不支持。 如果在启用Kerberos身份验证后尝试访问Solr Admin UI时看到401错误,则可能是浏览器未正确配置,无法知道如何或在何处协商身份验证请求。

有关如何设置浏览器的详细信息超出了本文档的范围; 请咨询您的系统管理员以获取有关如何配置浏览器的详细信息。

插件配置

咨询您的Kerberos管理员!
在尝试配置Solr以使用Kerberos身份验证之前,请查看下面概述的每个步骤,并咨询您的本地Kerberos管理员,以确保您知道每个参数的正确值。 小错误可能会导致Solr无法启动或无法正常工作,并且非常难以诊断。

Kerberos插件的配置有几个部分:

1 创建服务主体和密钥表文件

2 ZooKeeper配置

3 创建或更新/security.json

4 定义jaas-client.conf

5 Solr启动参数
我们将通过下面的每个步骤。
使用主机名
要使用主机名而不是IP地址,请在bin / solr.in.sh中使用SOLR_HOST配置,或在Solr启动过程中传递-Dhost = <主机名>系统参数。 本指南使用IP地址。 如果您指定主机名,请根据需要将指南中的所有IP地址替换为Solr主机名。

获取服务主体和密钥文件

在配置Solr之前,请确保您拥有适用于KDC服务器中每个Solr主机和ZooKeeper(如果尚未配置ZooKeeper)的Kerberos服务主体,并生成keytab文件,如下所示。

这个例子假定主机名是192.168.0.107,你的主目录是/ home / foo /。这个例子应该针对你自己的环境进行修改。

root@kdc:/# kadmin.local
Authenticating as principal foo/admin@EXAMPLE.COM with password.
kadmin.local: addprinc HTTP/192.168.0.107
WARNING: no policy specified for HTTP/192.168.0.107@EXAMPLE.COM; defaulting to no policy
Enter password for principal "HTTP/192.168.0.107@EXAMPLE.COM":
Re-enter password for principal "HTTP/192.168.0.107@EXAMPLE.COM":
Principal "HTTP/192.168.0.107@EXAMPLE.COM" created.
kadmin.local: ktadd -k /tmp/107.keytab HTTP/192.168.0.107
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/107.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/tmp/107.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/tmp/108.keytab.
Entry for principal HTTP/192.168.0.107 with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/tmp/107.keytab.
kadmin.local: quit

将keytab文件从KDC服务器的/tmp/107.keytab位置复制到/keytabs/107.keytab处的Solr主机。对每个Solr节点重复此步骤。

您可能需要采取类似的步骤来创建ZooKeeper服务主体和密钥表(如果尚未设置)。在这种情况下,下面的示例显示了ZooKeeper的一个不同的服务主体,因此可以使用zookeeper / host1作为其中一个节点的服务主体来重复上述操作.

ZooKeeper配置

如果您正在使用已配置为使用Kerberos的ZooKeeper,则可以跳过此处显示的与ZooKeeper相关的步骤。
由于ZooKeeper管理SolrCloud集群中节点之间的通信,因此它还必须能够与集群中的每个节点进行身份验证。 配置需要为ZooKeeper设置一个服务主体,定义一个JAAS配置文件并指示ZooKeeper使用这两个项目。
第一步是在ZooKeeper的conf目录下创建一个文件java.env并添加以下内容,如下例所示:
导出JVMFLAGS =“ - Djava.security.auth.login.config = / etc / zookeeper / conf / jaas-client.conf”
JAAS配置文件应该包含以下参数。 确保根据需要更改主体和keyTab路径。 该文件必须位于上述步骤中定义的路径中,并指定文件名。

Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/keytabs/zkhost1.keytab"
storeKey=true
doNotPrompt=true
useTicketCache=false
debug=true
principal="zookeeper/host1@EXAMPLE.COM";
};

最后,将以下行添加到ZooKeeper配置文件zoo.cfg中:

authProvider.1= org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000

一旦所有部分都到位,使用以下指向JAAS配置文件的参数启动ZooKeeper:

bin / zkServer.sh start -Djava.security.auth.login.config = / etc / zookeeper / conf / jaas-client.conf

创建 security.json

创建security.json文件。
在SolrCloud模式下,您可以将Solr设置为使用Kerberos插件,方法是在创建ZooKeeper时将security.json上载到ZooKeeper,如下所示:
server / scripts / cloud-scripts / zkcli.sh -zkhost localhost:2181 -cmd put /security.json'{“authentication”:{“class”:“org.apache.solr.security.KerberosPlugin”}}'
如果您在独立模式下使用Solr,则需要创建security.json文件并将其放入您的$ SOLR_HOME目录中。
有关如何在Solr中使用/security.json文件的更多详细信息,请参见身份验证和授权插件。
如果您已经在ZooKeeper中拥有/security.json文件,请下载该文件,添加或修改身份验证部分并使用Solr中提供的命令行实用程序将其上载回ZooKeeper。

定义JAAS配置文件

JAAS配置文件定义用于身份验证的属性,例如服务主体和keytab文件的位置。还可以设置其他属性以确保票证缓存和其他功能。

以下示例可以针对您的环境稍微复制和修改。文件的位置可以位于服务器上的任何位置,但启动Solr时会引用该文件,因此它必须在文件系统上可读。 JAAS文件可能包含不同用户的多个部分,但每个部分都必须具有唯一的名称,以便在每个应用程序中可以唯一地引用它。

在下面的例子中,我们创建了一个JAAS配置文件,其名称和路径为/home/foo/jaas-client.conf。我们将在下一节定义Solr开始参数时使用这个名称和路径。请注意,这里的客户主体与服务主体相同。这将用于验证节点间请求和请求到ZooKeeper。确保使用正确的主体主机名和keyTab文件路径。

Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/keytabs/107.keytab"
storeKey=true
useTicketCache=true
debug=true
principal="HTTP/192.168.0.107@EXAMPLE.COM";
};

该文件的第一行定义了部分名称,它将与下面定义的solr.kerberos.jaas.appname参数一起使用。
我们所关心的主要属性是keyTab和主要属性,但还有其他可能需要用于您的环境的属性。
Krb5LoginModule的javadoc(正在使用的类在上面的第二行中被调用)提供了可用属性的一个很好的轮廓,但为了参考,上面例子中使用的那些将在这里解释:
useKeyTab:这个布尔属性定义了我们是否应该使用keytab文件(在这种情况下为true)。
keyTab:JAAS配置文件的此部分用于主体的keytab文件的位置和名称。路径应该用双引号括起来。
storeKey:这个布尔属性允许密钥存储在用户的私人凭证中。
useTicketCache:该布尔属性允许从票证缓存中获取票证。
调试:此布尔属性将输出调试消息以帮助进行故障排除。
principal:要使用的服务主体的名称。

Solr启动参数

在启动Solr时,需要传递以下特定于主机的参数。 这些参数可以通过bin / solr start命令在命令行中传递(请参阅Solr控制脚本参考以了解有关如何传递系统参数的详细信息),或在bin / solr.in.sh或bin / solr.in.cmd中定义为 适合您的操作系统。

solr参数

这是一个可以添加到bin / solr.in.sh的例子。 确保将此示例更改为使用正确的主机名和密钥表文件路径。

SOLR_AUTH_TYPE="kerberos"
SOLR_AUTHENTICATION_OPTS="-Djava.security.auth.login.config=/home/foo/jaas-client.conf -Dsolr.kerberos.cookie.domain=192.168.0.107 -Dsolr.kerberos.cookie.portaware=true -Dsolr.kerberos.principal=HTTP/192.168.0.107@EXAMPLE.COM -Dsolr.kerberos.keytab=/keytabs/107.keytab"

使用委托令牌

Kerberos插件可以配置为使用委托令牌,允许应用程序重复使用最终用户或其他应用程序的身份验证。
Solr有几个用例可能会有所帮助:
使用分布式客户端(例如MapReduce),其中每个客户端可能无法访问用户的凭证。
在Kerberos服务器上加载时很高。 委托令牌可以减轻负载,因为它们在第一次请求后不访问服务器。
如果请求或权限需要委托给另一个用户。
要启用授权令牌,必须定义几个参数。 这些参数可以通过bin / solr start命令在命令行中传递(请参阅Solr控制脚本参考以了解有关如何传递系统参数的详细信息),或在bin / solr.in.sh或bin / solr.in.cmd中定义为 适合您的操作系统。


委托令牌

启动Solr

配置完成后,您可以使用bin / solr脚本启动Solr,如下面的示例所示,仅适用于SolrCloud模式的用户。 这个例子假设你修改了bin / solr.in.sh或者bin / solr.in.cmd,并带有正确的值,但是如果你没有修改,你可以将系统参数和start命令一起传递。 请注意,您还需要根据您的ZooKeeper节点的位置自定义-z属性。

bin/solr -c -z server1:2181,server2:2181,server3:2181/solr

测试配置

1、用你的用户名做一个kinit。 例如,kinit user@EXAMPLE.COM
2、尝试使用curl访问Solr。 你应该得到一个成功的回应。
curl --negotiate -u:“http://192.168.0.107:8983/solr/

使用SolrJ和Kerberized Solr

要在SolrJ应用程序中使用Kerberos身份验证,在创建SolrClient之前,需要以下两行:

System.setProperty(“java.security.auth.login.config”,“/home/foo/jaas-client.conf”);
HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());

您需要为客户端指定Kerberos服务主体,并在上面的JAAS客户端配置文件中指定相应的keytab。 该principal应与我们为Solr创建的service principal 不同。
下面是一个例子:

SolrJClient {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/keytabs/foo.keytab"
  storeKey=true
  useTicketCache=true
  debug=true
  principal="solrclient@EXAMPLE.COM";
};

SolrJ委托令牌

SolrJ也支持授权令牌,方法如下:
可以使用DelegationTokenRequest和DelegationTokenResponse来获取,取消和更新授权令牌。
HttpSolrClient.Builder包含一个withDelegationToken函数,用于创建一个使用委托令牌进行验证的HttpSolrClient。
获取授权令牌的示例代码:

private String getDelegationToken(final String renewer, final String user, HttpSolrClient solrClient) throws Exception {
    DelegationTokenRequest.Get get = new DelegationTokenRequest.Get(renewer) {
      @Override
      public SolrParams getParams() {
        ModifiableSolrParams params = new ModifiableSolrParams(super.getParams());
        params.set("user", user);
        return params;
      }
    };
    DelegationTokenResponse.Get getResponse = get.process(solrClient);
    return getResponse.getDelegationToken();
  }

创建使用委托令牌的HttpSolrClient:

HttpSolrClient client = new HttpSolrClient.Builder("http://localhost:8983/solr").withDelegationToken(token).build();

创建使用委托令牌的CloudSolrClient:

CloudSolrClient client = new CloudSolrClient.Builder()
                .withZkHost("http://localhost:2181")
                .withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder()
                    .withResponseParser(client.getParser())
                    .withHttpSolrClientBuilder(
                        new HttpSolrClient.Builder()
                            .withKerberosDelegationToken(token)
                    ))
                        .build();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 要加“m”说明是MB,否则就是KB了. -Xms:初始值 -Xmx:最大值 -Xmn:最小值 java -Xms8...
    dadong0505阅读 4,803评论 0 53
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,724评论 6 342
  • nexus 2.xxx安装 配置代理远程仓库:https://registry.npm.taobao.org/im...
    liurongming阅读 2,131评论 0 0
  • 一直以来默默关注着餐厅的进度 自己应该算是最不管事的股东了 心里相信即使拖延,店也一定会开起来 然后2月份群里部分...
    宁子smile阅读 365评论 0 0