《网安面试指南》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 的 CredentialsMatcher
有什么作用?如何实现自定义密码加密策略?
答案:
-
作用:用于验证用户提交的凭证(如密码)与存储的凭证是否匹配。
- 自定义加密步骤:
-
实现
CredentialsMatcher
:
public class BCryptMatcher implements CredentialsMatcher { public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { String inputPassword = new String((char[]) token.getCredentials()); String storedHash = (String) info.getCredentials(); return BCrypt.checkpw(inputPassword, storedHash); } }
-
配置 Realm:
[main] myRealm = com.example.MyRealm myRealm.credentialsMatcher = com.example.BCryptMatcher
-
2. Shiro 的 CacheManager
如何与 Redis 集成以提升性能?
答案:
-
使用
RedisCacheManager
:
public class RedisCacheManager implements CacheManager {
private RedisTemplate<String, Object> redisTemplate;
@Override
public <K, V> Cache<K, V> getCache(String name) {
return new RedisCache<>(name, redisTemplate);
}
}
-
配置 Shiro:
[main]
cacheManager = com.example.RedisCacheManager
securityManager.cacheManager = $cacheManager
- 优势:
-
减少数据库查询压力。
-
支持分布式环境下的缓存一致性。
-
3. 解释 Shiro 的 ThreadContext
及其在多线程环境下的潜在问题。
答案:
-
ThreadContext:基于
ThreadLocal
存储当前线程的 Shiro 状态(如 Subject、Session)。 - 多线程问题:
-
线程池复用:若主线程将 Subject 传递给子线程,可能导致状态污染或内存泄漏。
- 解决方案:
-
在子线程中手动绑定/解绑 Subject:
Subject subject = SecurityUtils.getSubject(); new Thread(() -> { ThreadContext.bind(subject); // 执行逻辑 ThreadContext.remove(); }).start();
-
使用
InheritableThreadLocal
配置(需谨慎,可能泄露敏感信息)。
-
-
4. Shiro 的 AuthorizationInfo
和 AuthenticationInfo
有什么区别?
答案:
- AuthenticationInfo:
-
用于认证阶段,存储用户身份凭证(如密码、盐值、哈希迭代次数)。
-
示例:
SimpleAuthenticationInfo(username, hashedPassword, salt, realmName)
。
-
- AuthorizationInfo:
-
用于授权阶段,存储用户的角色和权限集合。
-
示例:
SimpleAuthorizationInfo(roles, permissions)
。
-
- 关键区别:
-
AuthenticationInfo
关注“用户是谁”,AuthorizationInfo
关注“用户能做什么”。
-
5. Shiro 的 SessionDAO
接口设计有什么意义?如何实现会话持久化到数据库?
难度:⭐⭐⭐⭐
考察维度:会话管理、持久化设计
答案:
-
意义:解耦会话存储逻辑,支持灵活扩展(如 Redis、JDBC、Memory)。
- JDBC 持久化实现:
-
创建表结构(如
shiro_sessions
表)。 -
实现
JdbcSessionDAO
:
public class MyJdbcSessionDAO extends JdbcSessionDAO { @Override protected Serializable doCreate(Session session) { Serializable sessionId = generateSessionId(session); assignSessionId(session, sessionId); insertSession(session); // 插入数据库 return sessionId; } // 重写 read/update/delete 方法 }
-
配置
SessionManager
:
[main] sessionDAO = com.example.MyJdbcSessionDAO securityManager.sessionManager.sessionDAO = $sessionDAO
-
6. 如何利用 Shiro 的 EventBus
机制实现安全审计日志?
难度:⭐⭐⭐⭐⭐
考察维度:事件驱动、审计日志
答案:
-
监听 Shiro 事件(如登录成功、授权失败):
public class AuditLogListener implements EventListener {
@Subscribe
public void onLoginSuccess(LoginSuccessEvent event) {
Subject subject = event.getSubject();
log.info("User {} logged in from IP {}", subject.getPrincipal(), subject.getSession().getHost());
}
}
-
注册监听器:
EventBus eventBus = securityManager.getEventBus();
eventBus.register(new AuditLogListener());
- 应用场景:
-
记录异常登录尝试。
-
监控敏感操作(如权限变更)。
-