背景:
上文中在落地实践时,对Shiro进行了相关的配置,并未对其含义作用进行详细学习,本章将进一步详解其作用含义。
Shiro配置类中的各个配置项的作用:
@Beanpublic SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm()); securityManager.setSessionManager(defaultWebSessionManager()); securityManager.setCacheManager(ehCacheManager()); securityManager.setRememberMeManager(rememberMeManager()); return securityManager;}
securityManager()
方法创建一个DefaultWebSecurityManager
对象,并设置了相关的组件。DefaultWebSecurityManager
是 Shiro 的SecurityManager
实现类,用于管理所有的 Subject(用户)。setRealm(myRealm())
设置了自定义的Realm
对象,用于处理认证和授权逻辑。setSessionManager(defaultWebSessionManager())
设置了默认的SessionManager
对象,用于管理用户的会话信息。setCacheManager(ehCacheManager())
设置了 EhCache 缓存管理器,用于缓存用户信息和权限信息。setRememberMeManager(rememberMeManager())
设置了 RememberMeManager,用于实现 “记住我” 功能。
public class MyShiroRealm extends AuthorizingRealm { @Resource private UserInfoService userInfoService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { UserInfo userInfo = (UserInfo) principalCollection.getPrimaryPrincipal(); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (SysRole role : userInfo.getRoles()) { simpleAuthorizationInfo.addRole(role.getName()); for (SysPermission permission : role.getPermissions()) { simpleAuthorizationInfo.addStringPermission(permission.getName()); } } return simpleAuthorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { // 获取用户名 String username = (String) authenticationToken.getPrincipal(); // 根据username从数据库中查找 UserInfo 对象 UserInfo userInfo = userInfoService.findByUsername(username); if (null == userInfo) { return null; } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo( userInfo, // 用户名 userInfo.getPassword(), // 密码 ByteSource.Util.bytes(userInfo.getSalt()), // salt=username+salt getName() // realm name ); return simpleAuthenticationInfo; }}
MyShiroRealm 是一个自定义的Realm
对象继承 AuthorizingRealm ,并实现其两个方法,在这两个方法中进行认证和授权相关逻辑的编写。以便 login 执行的调用。
@Beanpublic DefaultWebSessionManager defaultWebSessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); sessionManager.setGlobalSessionTimeout(1800000); sessionManager.setSessionIdCookie(sessionIdCookie()); return sessionManager;}
defaultWebSessionManager()
方法创建一个DefaultWebSessionManager
对象,用于管理用户的会话信息。setGlobalSessionTimeout(1800000)
设置全局会话超时时间为30分钟。setSessionIdCookie(sessionIdCookie())
设置会话 ID 的 Cookie。
@Beanpublic SimpleCookie sessionIdCookie() { SimpleCookie cookie = new SimpleCookie("sid"); cookie.setHttpOnly(true); cookie.setMaxAge(-1); return cookie;}
sessionIdCookie()
方法创建一个SimpleCookie
对象,用于设置会话 ID 的 Cookie。setHttpOnly(true)
表示该 Cookie 只能通过 HTTP 协议获取,不能通过 JavaScript 等脚本语言获取,有助于防止跨站脚本攻击(XSS)。setMaxAge(-1)
表示该 Cookie 的有效期为浏览器会话结束时失效,即关闭浏览器后会话结束。
@Beanpublic EhCacheManager ehCacheManager() { EhCacheManager cacheManager = new EhCacheManager(); cacheManager.setCacheManagerConfigFile("classpath:ehcache.xml"); return cacheManager;}
ehCacheManager()
方法创建一个EhCacheManager
对象,用于缓存 Shiro 的数据。setCacheManagerConfigFile("classpath:ehcache.xml")
指定 EhCache 的配置文件位置。
@Beanpublic RememberMeManager rememberMeManager() { CookieRememberMeManager rememberMeManager = new CookieRememberMeManager(); rememberMeManager.setCookie(rememberMeCookie()); rememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag==")); return rememberMeManager;}
rememberMeManager()
方法创建一个RememberMeManager
对象,用于实现 “记住我” 功能。setCookie(rememberMeCookie())
设置 RememberMe 的 Cookie。setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="))
设置加密密钥,用于加密 “记住我” 的信息。
@Beanpublic SimpleCookie rememberMeCookie() { SimpleCookie cookie = new SimpleCookie("rememberMe"); cookie.setHttpOnly(true); cookie.setMaxAge(2592000); // 30 days return cookie;}
rememberMeCookie()
方法创建一个SimpleCookie
对象,用于设置 RememberMe 的 Cookie。setMaxAge(2592000)
设置 RememberMe 的 Cookie 有效期为 30 天。
小结:
通过对 Shiro 配置类中各个配置项的详细解释,可以更好地理解每个配置项的作用和含义,以及为什么要进行这些配置。这些配置项的设置可以根据具体的需求进行调整,以满足应用程序的安全性和功能性要求