# Heimdall 配置
从本章开始,我们将基于权限管理框架,逐步实现认证和授权功能。
# 实现 UserDetails
UserDetails 接口规定了认证授权的凭据格式,Heimdall 框架通过 UserDetails 确定唯一用户以及对用户信息进行缓存。 为了便于后续使用,在 UserDetails 中,可以附着自定义对象。 本例中,我们定义的 UserDetails 如下:
/**
* 自定义用户详情实体
*
* @author Luter
* @see UserDetails
* @see DefaultSimpleUserDetails
*/
@Data
@EqualsAndHashCode
@Accessors(chain = true)
@AllArgsConstructor
public class AppUserDetails implements UserDetails {
/**
* The User.
*/
private SysUserDTO user;
/**
* The Principal.
*/
private String principal;
/**
* Instantiates a new Default user detail.
*
* @param user the user
*/
public AppUserDetails(SysUserDTO user) {
this.user = user;
}
@Override
public String getPrincipal() {
return "APP:" + user.getId();
}
@Override
public boolean enabled() {
return user.getEnabled();
}
/**
* Gets user.
*
* @return the user
*/
public SysUserDTO getUser() {
return user;
}
/**
* Sets user.
*
* @param user the user
*/
public void setUser(SysUserDTO user) {
this.user = user;
}
/**
* Sets principal.
*
* @param principal the principal
*/
public void setPrincipal(String principal) {
this.principal = principal;
}
}
其中:getPrincipal()和 enabled()接口方法必须实现,以便 Heimdall 框架知道”是谁“以及"是否可用"
Heimdall 框架会将AppUserDetails 类信息,以 JSON 格式进行缓存。
# 实现 AuthorizationMetaDataService
AuthorizationMetaDataService 接口为 Heimdall 框架提供系统权限和用户权限数据。
系统权限规定了系统内哪些资源要进行权限管理。
用户权限规定了当前用户具备哪些系统权限。
实现如下:
/**
* 权限数据提供服务
*
* @author Luter
*/
@Service
@Slf4j
public class AuthorizationMetaDataServiceImpl implements AuthorizationMetaDataService {
/**
* The Sys resource service.
*/
@Autowired
private SysResourceService sysResourceService;
/**
* The Sys user service.
*/
@Autowired
private SysUserService sysUserService;
@Override
public Map<String, Collection<String>> loadSysAuthorities() {
final List<SysResourceDTO> objects = sysResourceService.listAll();
if (null != objects && !objects.isEmpty()) {
Map<String, Collection<String>> perms = new LinkedHashMap<>();
for (SysResourceDTO resource : objects) {
perms.put(resource.getUrl(), null);
}
log.warn("加载到的系统权限: \n{}", JacksonUtils.toPrettyJson(perms));
return perms;
}
return new LinkedHashMap<>();
}
@Override
public List<? extends GrantedAuthority> loadUserAuthorities(SimpleSession session) {
final AppUserDetails details = (AppUserDetails) session.getDetails();
final SysUserDTO user = details.getUser();
final SysUserDTO theUser = sysUserService.getById(user.getId());
final List<SysRoleDTO> roles = theUser.getRoles();
//通过用户角色获取用户权限,去重
if (null != roles && !roles.isEmpty()) {
List<SysResourceDTO> all = new ArrayList<>();
for (SysRoleDTO role : roles) {
if (null != role.getResources() && !role.getResources().isEmpty()) {
all.addAll(role.getResources());
}
}
final ArrayList<SysResourceDTO> userResources = all.stream().collect(collectingAndThen(toCollection(()
-> new TreeSet<>(comparing(SysResourceDTO::getId))), ArrayList::new));
//构造权限缓存信息
return userResources.stream().map(d -> new MethodAndUrlGrantedAuthority(d.getMethod(), d.getUrl())).collect(Collectors.toList());
}
return new ArrayList<>();
}
}
在系统资源服务中添加获取全部系统权限的方法以及实现:
List<SysResourceDTO> listAll();
@Override
public List<SysResourceDTO> listAll() {
final List<SysResourceEntity> all = sysResourceRepository.findAll();
return sysResourceMapper.entityListToDTOList(all);
}
# Heimdall 安全配置
新建 HeimdallConfig配置,内容如下:
/**
* Heimdall 安全配置
*
* @author Luter
*/
@Configuration
@Slf4j
public class HeimdallConfig {
/**
* SessionDao 配置
*
* @param servletHolder the servlet holder
* @return the session dao
*/
@Bean
public SessionDAO sessionDAO(ServletHolder servletHolder) {
log.warn("初始化 SessionDAO");
return new CaffeineSessionDaoImpl(servletHolder);
}
/**
* 认证管理器
*
* @param sessionDAO the session dao
* @return the authentication manager
*/
@Bean
public AuthenticationManager authenticationManager(SessionDAO sessionDAO) {
log.warn("初始化 认证管理器");
return new AuthenticationManager(sessionDAO);
}
/**
* 权限缓存Dao,注册此 Bean 便于进行动态授权
*
* @return the authorization meta data cache dao
*/
@Bean
public AuthorizationMetaDataCacheDao authorizationMetaDataCacheDao() {
log.warn("初始化 系统权限数据 MetaDataDao");
return new CaffeineAuthorizationMetaDataDao();
}
/**
* 授权管理器
*
* @param authenticationManager the authentication manager
* @param authorizationMetaDataService the authorization meta data service
* @return the authorization manager
*/
@Bean
public AuthorizationManager authorizationManager(AuthenticationManager authenticationManager
, AuthorizationMetaDataService authorizationMetaDataService, AuthorizationMetaDataCacheDao authorizationMetaDataCacheDao) {
log.warn("初始化 授权管理器");
return new AuthorizationManager(authorizationMetaDataService,
authorizationMetaDataCacheDao, authenticationManager);
}
}
至此,Heimdall 权限管理配置完毕。此时访问资源端点:/pet/cats ,将会提示需要登录。
下章开始,我们将实现登录、注销、在线用户管理等功能。