「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」。
承接上文...
3.2 设计数据类
完成数据库设计后, 再根据表的内容完成数据类的创建, 由于字段较多, 除了用户类之外, 我们只列举出权限相关的关键属性
权限类Permission
:
@Data
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
public class Permission {
// ...
protected List<Api> apis;
}
角色类Role
:
@Data
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
public class Role {
// ...
protected List<Permission> permissions;
}
用户类User
:
@Data
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
public class User {
protected String id;
protected String username;
protected String password;
protected String name;
protected List<Role> roles;
}
3.3 实现UserDetails
UserDetails是Spring Security中用户信息的来源, 用户账号密码校验/权限校验都要依托于此
想要实现RBAC模型的权限管理, 需要手动实现自己的UserDetails
先来看一下UserDetails的官方文档:
getUsername
/getPassword
方法不必多说, 重要的是 getAuthorities
方法, 它提供了用户的权限信息, 并用此信息进行权限校验
源码中包含了一个实现UserDetails的User类, 可以作为参照
修改上一节中设计的用户类, 让它实现UserDetails
:
@Data
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
public class User implements UserDetails {
protected String id;
protected String username;
protected String password;
protected String name;
protected List<Role> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return false;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return true;
}
}
根据RBAC权限模型, 编写getAuthorities
方法:
@Data
@NoArgsConstructor
@SuperBuilder(toBuilder = true)
public class User implements UserDetails {
protected String id;
protected String username;
protected String password;
protected String name;
protected List<Role> roles;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
HashSet<Permission> permissions = new HashSet<>();
roles.forEach(role -> permissions.addAll(TreeUtil.extract(role.getPermissions())));
HashSet<Api> apis = new HashSet<>();
permissions.forEach(permission -> apis.addAll(permission.getApis()));
return apis.stream().map(api -> new SimpleGrantedAuthority(api.getCode()))
.collect(Collectors.toList());
}
}