Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
hel-developer-guide
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hel-guide
hel-developer-guide
Commits
6f7babed
Commit
6f7babed
authored
Aug 02, 2017
by
高洋
Browse files
Options
Browse Files
Download
Plain Diff
Conflict resolution
parents
f5d5dc1f
9c1ae692
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
394 additions
and
0 deletions
+394
-0
audit.md
后端开发/audit.md
+75
-0
lock.md
后端开发/lock.md
+240
-0
user-security-strategy.md
后端开发/user-security-strategy.md
+79
-0
No files found.
后端开发/audit.md
0 → 100644
View file @
6f7babed
审计
---
融租易支持在代码级别记录用户对指定表的操作记录.
操作包括 : 插入, 更新, 删除.
## 1. 代码准备
再代码层面, 有两个注解
`AuditEnabled`
,
`AuditEntry`
#### 1.1 AuditEnabled
这个注解加在 DTO 类上, 表示这个 DTO 代表的 表需要开启审计功能.
```
java
@Table
(
"SYS_USER"
)
@AuditEnabled
public
class
User
{
}
```
#### 1.2 AuditEntry
这个注解加在
`Service 接口的方法`
上, 表示, 再这个方法的执行周期内开启审计功能.
> 这个方法内部可能会对多个表进行操作, 也可能调用其他的方法 f1, f1 在去操作其他的某个表.
这些调用涉及到的审计操作, 全部共享一个审计的 session (auditSessionId相同).
```
java
public
interface
UserService
{
@AuditEntry
User
updateUser
(
User
user
);
}
```
## 2. 表结构
所有需要开启审计功能的表, 需要有一个与之相对应的
`审计表`
.
命名规则 :
`基表名`
_a
可以在
`AuditEnabled`
注解中通过参数
`auditTable`
来指定.
>这个规则可以 实现接口 `IAuditTableNameProvider` 来自定义.
实现类需要定义为 spring bean
审计表字段
`包含所有字段`
, 但不包含
`基表的唯一索引, 主键约束`
等
另外必须包括审计专用字段:
*
`audit_id`
(bigint) 自增长主键
*
`audit_transaction_type`
(varchar (10)) 审计操作(insert,update,delete)
*
`audit_timestamp`
(datetime) 审计时间
*
`audit_session_id`
(varchar(64)) 审计 session id
## 3 基本原理
`AuditInterceptor`
会拦截所有的 Mybatis 通过 dto 执行的操作,
根据当前有没有
`audit session`
, 以及 dto 上的 AuditEnabled 注解 来决定是不是要执行 审计操作.
如果需要执行, 则动态生成 SQL 语句, 完成对新记录的
`备份`
操作.
`插入`
,
`更新`
执行的操作是 先操作, 后记录.
`删除`
执行的操作是 先记录, 后操作.
也就是说, 审计表中插入的都是
`最新的快照`
.
> 基于这个原理的审计, 只能做到行级的记录, 无法具体到字段级.
但是结合一定的比较手段, 可以知道, 某次修改, 到底修改了哪些字段.
另外, 由于 audit session 的存在, 我们大概也可以知道,某次提交,同时修改了哪些数据.
当然操作的记录如何展示出来, 是需要另外开发页面的.
\ No newline at end of file
后端开发/lock.md
0 → 100644
View file @
6f7babed
# 锁机制
融租易提供两种锁机制, 满足项目上对数据并发修改的需求.
## 1.数据库锁
***
根据适当的参数进行物理锁定(数据库级锁),支持3种数据库:oracle,mysql,sqlserver。提供 API, 自动执行 sql
>
mysql,orcale 执行 select
*
from xxx where ... for update
> sqlserver 执行 select * from xxx with (ROWLOCK) where ...
> 都是数据库原生的锁机制
使用方式:
### 单数据源
在Java代码中,注入
`DatabaseLockProvider`
类,
```
java
public
class
XXXServiceImpl
{
@Autowired
private
DatabaseLockProvider
databaseLockProvider
;
public
int
update
(
XXX
dto
,
...){
// 传入锁定对象,锁定数据库相关行
databaseLockProvider
.
lock
(
dto
);
//...
}
}
```
### 多数据源
在Java代码中,
`自己创建DatabaseLockProvider类`
,指定
`dataSource`
```
java
public
class
XXXServiceImpl
{
@Autowired
@Qualifier
(
"xxxDataSource"
)
private
DataSource
dataSource
;
private
DatabaseLockProvider
databaseLockProvider
;
@Transactional
(
propagation
=
Propagation
.
REQUIRED
)
public
int
update
(
XXX
dto
,
...){
databaseLockProvider
=
new
DatabaseLockProvider
(
dataSource
)
// 传入锁定对象,锁定数据库相关行
databaseLockProvider
.
lock
(
dto
);
//...
}
}
```
> 事务提交以后,锁会自动释放
DatabaseLockProvider提供的接口
```
java
//根据传入对象,自动加锁。
//确保bean上有@Table 注解,能自动解析出对应的表。 默认根据有@ID注解的字段进行加锁,确保id有值
public
void
lock
(
Object
dto
)
//根据传入对象和自定义的where条件,自动加锁。
//传入类似 "name = ? and age = ?" 的条件语句,根据whereCondition,依次对应传入属性对应的值。
public
void
lock
(
Object
dto
,
String
whereCondition
,
Object
...
whereParameter
)
// 可以自定义表名,不必传入dto
public
void
lock
(
String
tableName
,
String
whereCondition
,
Object
...
whereParameter
)
```
## 2.分布式锁
基于
`redis`
的锁,实现跨平台, 分布式锁
使用方式:
1.
根据实际配置的redis,修改配置文件
`config.properties`
```
properties
redisson.server.url
=
127.0.0.1:6379
#redissson.server.password=
```
> 支持`多节点`配置,按照如下规范配置
>redisson.server.url=\
> 127.0.0.1:6379,\
> 10.211.103.142:6379
>内部使用redisson提供的`RedLock`进行加锁
2.
在java代码中注入DistributedLockProvider
```
java
public
class
XXXServiceImpl
{
@Autowired
@Qualifier
(
"distributeLockTemplate"
)
private
DistributedLockProvider
distributedLockProvider
;
public
int
update
(
XXX
dto
,
...){
//使用回调方式,执行自己的业务逻辑
distributedLockProvider
.
lock
(
dto
,
new
DistributedLockCallback
<
Object
>()
{
@Override
public
Object
process
()
{
//doSomething();
return
null
;
})
}
}
```
> 回调函数执行以后,锁都会自动释放
DistributedLockProvider提供的接口:
```
java
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @return 回调函数返回的内容
*/
<
T
>
T
lock
(
Object
lockKey
,
DistributedLockCallback
<
T
>
callback
);
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 确保唯一
* @param callback
* @return 回调函数返回的内容
*/
<
T
>
T
lock
(
String
lockKey
,
DistributedLockCallback
<
T
>
callback
);
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* @return 回调函数返回的内容
*/
<
T
>
T
lock
(
Object
lockKey
,
DistributedLockCallback
<
T
>
callback
,
long
leaseTime
,
TimeUnit
timeUnit
);
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 确保唯一
* @param callback
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* @return 回调函数返回的内容
*/
<
T
>
T
lock
(
String
lockKey
,
DistributedLockCallback
<
T
>
callback
,
long
leaseTime
,
TimeUnit
timeUnit
);
/**
* 使用分布式锁,使用锁默认超时时间。
*
* @param lockKey
* 确保唯一
* @param callback
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<
T
>
T
tryLock
(
String
lockKey
,
DistributedLockCallback
<
T
>
callback
)
throws
Exception
;
/**
* 使用分布式锁,使用锁默认超时时间。默认等待时间1秒
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<
T
>
T
tryLock
(
Object
lockKey
,
DistributedLockCallback
<
T
>
callback
)
throws
Exception
;
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 加锁对象,确保有@ID属性,建议BaseDto
* @param callback
* @param waitTime
* 获取锁等待时间,超过设置时间未获得锁则抛出异常
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* waitTime,leaseTime 时间单位
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<
T
>
T
tryLock
(
Object
lockKey
,
DistributedLockCallback
<
T
>
callback
,
long
waitTime
,
long
leaseTime
,
TimeUnit
timeUnit
)
throws
Exception
;
/**
* 使用分布式锁。自定义锁的超时时间
*
* @param lockKey
* 确保唯一
* @param callback
* @param waitTime
* 获取锁等待时间,超过设置时间未获得锁则抛出异常
* @param leaseTime
* 锁超时时间。超时后自动释放锁。
* @param timeUnit
* waitTime,leaseTime 的时间单位
* @return 回调函数返回的内容
*
* @exception Exception 加锁过程的异常,比如锁已被占用,加锁失败
*/
<
T
>
T
tryLock
(
String
lockKey
,
DistributedLockCallback
<
T
>
callback
,
long
waitTime
,
long
leaseTime
,
TimeUnit
timeUnit
)
throws
Exception
;
```
后端开发/user-security-strategy.md
0 → 100644
View file @
6f7babed
# 用户安全策略
框架提供标准的用户安全策略接口
com.hand.hap.security.IUserSecurityStrategy
> 默认实现DefaultUserSecurityStrategy,order值为9999
编写自定义实现类,需要在 Spring 中定义为 bean (也可以通过 @Component之类的注解自动扫描注册)
可以实现下列方法,自定义安全策略:
### 登录成功以后,跳转至index页面前的策略
```
java
ModelAndView
loginVerifyStrategy
(
User
user
,
HttpServletRequest
request
);
```
参数及返回类型说明
> - user 通过登录验证的User对象
-
ModelAndView 重定向到该 ModelAndView
>
如果想要正常跳转到index页面,请返回null
注意:会根据order大小依次执行实现类的该方法,注意顺序
### 用户修改密码时,自定义密码复杂度
```
java
void
passwordVerifyStrategy
(
IRequest
request
,
User
user
,
String
oldPwd
,
String
newPwd
,
String
newPwdAgain
)
throws
UserException
;
```
参数及异常说明
> - user 通过登录验证的User对象
-
oldPwd 旧密码
-
newPwd 新密码
-
newPwdAgain 再次输入的新密码
-
如果验证不通过,请抛出自定义的UserException
一般来说修改了复杂度验证策略,需要修改sys_config页面。
### 新建用户时的策略
```
java
User
beforeCreateUser
(
IRequest
request
,
User
user
)
```
可以对用户做统一的信息处理,如统一设置一些属性值,注意如果实现了该方法,一定要返回处理后的User对象,默认返回传入的user
> 实现IAuthenticationSuccessListener
接口, 是在用户登录验证成功时执行.
>
一般用来往session里面放一些值,或其他逻辑,如果抛出异常,则会在login页面显示异常信息,注意区别。
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment