给自己看的:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>com.github.theborakompanioni</groupId> <artifactId>thymeleaf-extras-shiro</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nokohtml库 让Spring boot的thymeleaf模板不严格检查html --> <dependency> <groupId>net.sourceforge.nekohtml</groupId> <artifactId>nekohtml</artifactId> <version>1.9.22</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-web --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency> <!-- shiro ehcache --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency>
@Configuration public class ShiroConfiguration { private final Logger logger = LoggerFactory.getLogger(ShiroConfiguration.class); //权限过滤 @Bean(name="shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) { ShiroFilterFactoryBean bean=new ShiroFilterFactoryBean(); bean.setSecurityManager(manager); //配置登录的url和登录成功的url bean.setLoginUrl("/loginHtml"); //未授权界面; // bean.setUnauthorizedUrl("/notFound"); //配置访问权限的路劲 LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>(); filterChainDefinitionMap.put("/css/**","anon"); filterChainDefinitionMap.put("/images/**","anon"); filterChainDefinitionMap.put("/js/**","anon"); filterChainDefinitionMap.put("/lib/**","anon"); filterChainDefinitionMap.put("/websocket/**","anon"); filterChainDefinitionMap.put("/login.html","anon"); filterChainDefinitionMap.put("/swagger-resources/**", "anon"); //swagger filterChainDefinitionMap.put("/v2/api-docs/**", "anon"); //swagger filterChainDefinitionMap.put("/webjars/**","anon"); //swagger filterChainDefinitionMap.put("/swagger-ui.html","anon"); //swagger filterChainDefinitionMap.put("/login","anon");//表示可以匿名访问 filterChainDefinitionMap.put("/logout*","anon"); filterChainDefinitionMap.put("/*.html","authc"); filterChainDefinitionMap.put("/*", "authc");//authc表示需要认证才可以访问 filterChainDefinitionMap.put("/**", "authc"); filterChainDefinitionMap.put("/*.*", "authc"); bean.setFilterChainDefinitionMap(filterChainDefinitionMap); return bean; } //配置核心安全事务管理器 @Bean(name="securityManager") public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm, @Qualifier("sessionManager") DefaultWebSessionManager sessionManager ) { logger.debug("--------------shiro已经加载----------------"); DefaultWebSecurityManager manager=new DefaultWebSecurityManager(); manager.setRealm(authRealm); manager.setSessionManager(sessionManager); ///注入缓存管理器 manager.setCacheManager(ehCacheManager()); //注入Cookie(记住我)管理器(remenberMeManager) manager.setRememberMeManager(rememberMeManager()); return manager; } //配置自定义的权限登录器 @Bean(name="authRealm") public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) { AuthRealm authRealm=new AuthRealm(); authRealm.setCredentialsMatcher(matcher); return authRealm; } //配置自定义的密码比较器 @Bean(name="credentialsMatcher") public CredentialsMatcher credentialsMatcher() { return new CredentialsMatcher(); } /** * 定义无法确定init()或destory()方法已经被调用 * @return */ @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){ return new LifecycleBeanPostProcessor(); } /** * 实现spring的自动代理 * @return */ @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator(); creator.setProxyTargetClass(true); return creator; } //自定义权限注解 @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) { AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor(); advisor.setSecurityManager(manager); return advisor; } /** * 配置html页面能使用shiro标签 * @return */ @Bean(name = "shiroDialect") public ShiroDialect shiroDialect(){ return new ShiroDialect(); } @Bean public EhCacheManager ehCacheManager(){ EhCacheManager cacheManager = new EhCacheManager(); cacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml"); return cacheManager; } @Bean public SimpleCookie rememberMeCookie(){ //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); //<!-- 记住我cookie生效时间30天 ,单位秒;--> simpleCookie.setMaxAge(259200); return simpleCookie; } /** * cookie管理对象; * @return */ @Bean public CookieRememberMeManager rememberMeManager(){ CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie()); return cookieRememberMeManager; } @Bean(name="sessionManager") public DefaultWebSessionManager sessionManager(){ DefaultWebSessionManager sessionManager=new DefaultWebSessionManager(); // sessionManager.setSessionDAO(redisSessionDAO()); sessionManager.setGlobalSessionTimeout(1800000); sessionManager.setSessionValidationInterval(1200000); sessionManager.setSessionIdUrlRewritingEnabled(false); sessionManager.setSessionValidationSchedulerEnabled(true); return sessionManager; } }
public class AuthRealm extends AuthorizingRealm { private final Logger logger = LoggerFactory.getLogger(AuthRealm.class); @Autowired private SimpMessagingTemplate messagingTemplate; //认证,登录 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken tokens) throws AuthenticationException { UsernamePasswordToken token=(UsernamePasswordToken)tokens;//获取用户输入的token String username=token.getUsername(); String password=new String(token.getPassword()); User user=new User(); user.setUsername(username); user.setPassword("123456"); SessionsSecurityManager securityManager = (SessionsSecurityManager) SecurityUtils.getSecurityManager(); DefaultSessionManager sessionManager = (DefaultSessionManager) securityManager.getSessionManager(); Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();//获取当前已登录的用户session列表 for (Session session : sessions) { User users = (User) (session.getAttribute("USER_IN_SESSION")); if (users != null) { if (username.equals(users.getUsername())&&password.equals(users.getPassword())) { if(SecurityUtils.getSubject().getSession().getId().equals(session.getId())){ break; }else { logger.debug(username + "已登录,移除以保存的session"); sessionManager.getSessionDAO().delete(session); messagingTemplate.convertAndSendToUser(username, "/queue/message", new WiselyResponse("该账号已在其他机器登陆!")); } } } } SimpleAuthenticationInfo ai=new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());//放入shiro.调用CredentialsMatcher检验密码 return ai; } //授权 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(); User user=(User)principal.fromRealm(this.getClass().getName()).iterator().next(); List<String> permission=new ArrayList<>(); info.addStringPermissions(permission); return info; } }
public class CredentialsMatcher extends SimpleCredentialsMatcher{ //密码的校验 public boolean doCredentialsMatch(AuthenticationToken authToken, AuthenticationInfo info){ UsernamePasswordToken token=(UsernamePasswordToken)authToken; String password=new String(token.getPassword());//获取用户输入密码 //password=ShiroHashMd5.setPassword(password); String dbPassword=(String) info.getCredentials();//获取数据库密码 return this.equals(password,dbPassword); } }
public class MyAuthenticator extends Authenticator { private String userName=""; private String password=""; public MyAuthenticator(String userName, String password){ this.userName=userName; this.password=password; } protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication(userName, password); } }
<?xml version="1.0" encoding="UTF-8"?> <ehcache name="es"> <diskStore path="java.io.tmpdir"/> <!-- name:缓存名称。 maxElementsInMemory:缓存最大数目 maxElementsOnDisk:硬盘最大缓存个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 overflowToDisk:是否保存到磁盘,当系统当机时 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 memoryStoreEvictionPolicy: Ehcache的三种清空策略; FIFO,first in first out,这个是大家最熟的,先进先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" /> <!-- 登录记录缓存锁定10分钟 --> <cache name="passwordRetryCache" maxEntriesLocalHeap="2000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="0" overflowToDisk="false" statistics="true"> </cache> </ehcache>