RuoYi-Cloud-Plus SaToken鉴权
管理员拥有所有权限src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java#getMenuPermission()配置白名单src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java。内网鉴权src/main/jav
SaToken 鉴权
@SaCheckPermission
StpLogic#checkPermissionAnd
public void checkPermissionAnd(String... permissionArray) {
Object loginId = this.getLoginId();
List<String> permissionList = this.getPermissionList(loginId);
String[] var4 = permissionArray;
int var5 = permissionArray.length;
for(int var6 = 0; var6 < var5; ++var6) {
String permission = var4[var6];
if (!this.hasElement(permissionList, permission)) {
throw (new NotPermissionException(permission, this.loginType)).setCode(11051);
}
}
}
public void checkPermissionOr(String... permissionArray) {
Object loginId = this.getLoginId();
List<String> permissionList = this.getPermissionList(loginId);
String[] var4 = permissionArray;
int var5 = permissionArray.length;
for(int var6 = 0; var6 < var5; ++var6) {
String permission = var4[var6];
if (this.hasElement(permissionList, permission)) {
return;
}
}
if (permissionArray.length > 0) {
throw (new NotPermissionException(permissionArray[0], this.loginType)).setCode(11051);
}
}
StpInterface#getPermissionList()获取权限列表
List<String> getPermissionList(Object var1, String var2);
在线用户src/main/java/com/ruoyi/auth/listener/UserActionListener.java
/**
* 每次登录时触发
*/
@Override
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
UserType userType = UserType.getUserType(loginId.toString());
if (userType == UserType.SYS_USER) {
UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = ServletUtils.getClientIP();
LoginUser user = LoginHelper.getLoginUser();
SysUserOnline userOnline = new SysUserOnline();
userOnline.setIpaddr(ip);
userOnline.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
userOnline.setBrowser(userAgent.getBrowser().getName());
userOnline.setOs(userAgent.getOs().getName());
userOnline.setLoginTime(System.currentTimeMillis());
userOnline.setTokenId(tokenValue);
userOnline.setUserName(user.getUsername());
if (ObjectUtil.isNotNull(user.getDeptName())) {
userOnline.setDeptName(user.getDeptName());
}
if(tokenConfig.getTimeout() == -1) {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline);
} else {
RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, userOnline, Duration.ofSeconds(tokenConfig.getTimeout()));
}
log.info("user doLogin, useId:{}, token:{}", loginId, tokenValue);
} else if (userType == UserType.APP_USER) {
// app端 自行根据业务编写
}
}
全局过滤,白名单操作
src/main/java/com/ruoyi/gateway/filter/AuthFilter.java#getSaReactorFilter
@Configuration
public class AuthFilter {
/**
* 注册 Sa-Token 全局过滤器
*/
@Bean
public SaReactorFilter getSaReactorFilter(IgnoreWhiteProperties ignoreWhite) {
return new SaReactorFilter()
// 拦截地址
.addInclude("/**")
.addExclude("/favicon.ico", "/actuator/**")
// 鉴权方法:每次访问进入
.setAuth(obj -> {
// 登录校验 -- 拦截所有路由
SaRouter.match("/**")
.notMatch(ignoreWhite.getWhites())
.check(r -> {
// 检查是否登录 是否有token
StpUtil.checkLogin();
// 有效率影响 用于临时测试
// if (log.isDebugEnabled()) {
// log.debug("剩余有效时间: {}", StpUtil.getTokenTimeout());
// log.debug("临时有效时间: {}", StpUtil.getTokenActivityTimeout());
// }
});
}).setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED));
}
}
配置白名单src/main/java/com/ruoyi/gateway/config/properties/IgnoreWhiteProperties.java
@Data
@NoArgsConstructor
@Configuration
@RefreshScope
@ConfigurationProperties(prefix = "security.ignore")
public class IgnoreWhiteProperties {
/**
* 放行白名单配置,网关不校验此处的白名单
*/
private List<String> whites = new ArrayList<>();
}
内网鉴权src/main/java/com/ruoyi/gateway/filter/ForwardAuthFilter.java
/**
* 转发认证过滤器(内部服务外网隔离)
*
* @author Lion Li
*/
@Component
public class ForwardAuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest newRequest = exchange
.getRequest()
.mutate()
// 为请求追加 Same-Token 参数
.header(SaSameUtil.SAME_TOKEN, SaSameUtil.getToken())
.build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
}
@Override
public int getOrder() {
return -100;
}
}
安全校验依赖项
<!-- RuoYi Common Security -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId>
</dependency>
src/main/java/com/ruoyi/common/security/config/SecurityConfiguration.java#getSaServletFilter()
/**
* 校验是否从网关转发
*/
@Bean
public SaServletFilter getSaServletFilter() {
return new SaServletFilter()
.addInclude("/**")
.addExclude("/actuator/**")//排除了健康检测的监控
.setAuth(obj -> SaSameUtil.checkCurrentRequestToken())
.setError(e -> SaResult.error("认证失败,无法访问系统资源").setCode(HttpStatus.UNAUTHORIZED));
}
管理员拥有所有权限src/main/java/com/ruoyi/system/service/impl/SysPermissionServiceImpl.java#getMenuPermission()
/**
* 获取菜单数据权限
*
* @param user 用户
* @return 菜单权限信息
*/
@Override
public Set<String> getMenuPermission(SysUser user) {
Set<String> perms = new HashSet<String>();
// 管理员拥有所有权限
if (LoginHelper.isAdmin(user.getUserId())) {
perms.add("*:*:*");
} else {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
}
return perms;
}
}
src/main/java/com/ruoyi/system/dubbo/RemoteUserServiceImpl.java
@Override
public LoginUser getUserInfo(String username) throws UserException {
SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserName, SysUser::getStatus)
.eq(SysUser::getUserName, username));
if (ObjectUtil.isNull(sysUser)) {
throw new UserException("user.not.exists", username);
}
if (UserStatus.DISABLE.getCode().equals(sysUser.getStatus())) {
throw new UserException("user.blocked", username);
}
// 此处可根据登录用户的数据不同 自行创建 loginUser
return buildLoginUser(userMapper.selectUserByUserName(username));
}
/**
* 构建登录用户
*/
private LoginUser buildLoginUser(SysUser user) {
LoginUser loginUser = new LoginUser();
loginUser.setUserId(user.getUserId());
loginUser.setDeptId(user.getDeptId());
loginUser.setUsername(user.getUserName());
loginUser.setPassword(user.getPassword());
loginUser.setUserType(user.getUserType());
loginUser.setMenuPermission(permissionService.getMenuPermission(user));
loginUser.setRolePermission(permissionService.getRolePermission(user));
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
loginUser.setRoles(roles);
return loginUser;
}
更多推荐
所有评论(0)