25年护网二面
《网安面试指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token=1860256701&lang=zh_CN
5000篇网安资料库https://mp.weixin.qq.com/s?__biz=MzkwNjY1Mzc0Nw==&mid=2247486065&idx=2&sn=b30ade8200e842743339d428f414475e&chksm=c0e4732df793fa3bf39a6eab17cc0ed0fca5f0e4c979ce64bd112762def9ee7cf0112a7e76af&scene=21#wechat_redirect
苦逼的技术,能干销售就去干销售吧,毕竟年轻不干,35+还是得去干,要不你就专研技术不可替代。那就看看下面这些关于Shiro相关的面试题你懂不?
1. Shiro 的核心架构包含哪些组件?请简述其交互流程。
答案:
Shiro 核心组件包括:
-
Subject:当前用户或系统的抽象,封装操作(登录、权限校验等)。
-
SecurityManager:核心安全管理器,管理所有 Subject 的生命周期和安全操作。
-
Realm:数据源适配器,负责从数据库、LDAP 等加载认证和授权数据。
-
Authenticator:执行认证逻辑(如用户名密码校验)。
-
Authorizer:执行授权逻辑(如角色/权限校验)。
-
SessionManager:管理用户会话,支持分布式环境。
交互流程:
-
用户调用
Subject.login(token)
→SecurityManager
委托Authenticator
→Authenticator
调用Realm
获取认证信息 → 校验成功后建立会话(Session)。
2. Shiro 的 RememberMe
功能存在哪些安全风险?如何防御(如 Shiro-550 漏洞)?
答案:
- 风险(Shiro-550):
-
硬编码密钥:默认
AES
加密密钥硬编码在源码中,攻击者可伪造 RememberMe Cookie 触发反序列化漏洞。 -
利用链:构造恶意序列化数据 → 加密后写入 Cookie → Shiro 解密后反序列化执行任意代码。
-
- 防御措施:
-
升级版本:升级到 1.2.5+ 并更换自定义密钥(
shiro.rememberMe.cipherKey
)。 -
禁用反序列化:配置
securityManager.rememberMeManager.cipherService
为AesCipherService
,禁用危险类。 -
过滤输入:拦截非法 Cookie 格式(如非 Base64 内容)。
-
3. 如何自定义 Shiro 的 Realm
实现多数据源认证(如同时验证数据库和 LDAP)?
答案:
实现 ModularRealmAuthenticator
并重写 doMultiRealmAuthentication
方法:
public class MultiSourceAuthenticator extends ModularRealmAuthenticator {
@Override
protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {
for (Realm realm : realms) {
if (realm.supports(token)) {
AuthenticationInfo info = realm.getAuthenticationInfo(token);
if (info != null) return info; // 任一 Realm 成功即通过
}
}
throw new AuthenticationException("All realms failed");
}
}
配置 shiro.ini
:
[main]
authenticator = com.example.MultiSourceAuthenticator
securityManager.authenticator = $authenticator
dbRealm = com.example.DatabaseRealm
ldapRealm = com.example.LdapRealm
securityManager.realms = $dbRealm, $ldapRealm
4. Shiro 的 Session
管理如何实现分布式一致性?请对比 Redis 和 Hazelcast 方案。
答案:
- 实现原理:
-
Redis:通过
RedisSessionDAO
将会话数据存储到 Redis,支持高可用和持久化。 -
Hazelcast:利用内存网格(IMDG)实现分布式内存存储,低延迟但依赖集群内网通信。
-
- 对比:
维度 Redis Hazelcast 数据持久化 支持(RDB/AOF) 仅内存(需配置持久化策略) 性能 高吞吐(网络延迟敏感) 低延迟(本地缓存优先) 部署复杂度 独立部署,需维护 Redis 集群 去中心化,节点自发现 适用场景 大规模分布式系统 中小规模集群或内网环境
5. Shiro 的权限校验(如 isPermitted
)在底层是如何实现的?
答案:
-
调用链:
Subject.isPermitted()
→AuthorizingSecurityManager
→ModularRealmAuthorizer
→Realm.getAuthorizationInfo()
→PermissionResolver
解析权限字符串。 - 核心逻辑:
-
权限字符串格式:
资源:操作:实例
(如user:delete:123
)。 -
校验时通过
WildcardPermission
匹配规则,如user:*
允许所有用户操作。
-
-
缓存优化:授权信息默认通过
AuthorizationCache
缓存,避免频繁查询数据库。
6. 如何利用 Shiro 的 Filter
机制实现 IP 白名单访问控制?
答案:
-
自定义
AccessControlFilter
:
public class IpWhitelistFilter extends AccessControlFilter {
private Set<String> allowedIps = new HashSet<>();
@Override
protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
String ip = request.getRemoteAddr();
return allowedIps.contains(ip);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) {
response.getWriter().write("IP denied");
return false;
}
}
-
配置
shiro.ini
:
[urls]
/admin/** = ipWhitelist, authc
[main]
ipWhitelist = com.example.IpWhitelistFilter
ipWhitelist.allowedIps = 192.168.1.1, 10.0.0.1