`
hbxflihua
  • 浏览: 660068 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

整合spring、shiro、redis实现会话共享

阅读更多

 什么是Shiro?

Apache旗下强大灵活的开源安全框架

提供认证、授权、会话管理、安全加密等功能

 

 

Shiro整体架构

 

SecurityManager Shiro的核心,Shiro通过SecurityManager 提供安全服务;

Authenticator 认证器,管理主体的登录、登出;

Authorizer 授权器,赋予主体有哪些权限;

SessionManager Session管理器,可以脱离web容器;

SessionDao 提供Session的增删改查操作;

CacheManager 缓存管理器,可以缓存主体的角色、权限数据;

Realm Shiro和数据源之间的桥梁,通过Realm获取认证、角色和权限数据等

 

主体提交请求到SecurityManagerSecurityManager调用Authenticator对主体进行认证。Authenticator通过Realm来获取认证信息,和主体提交的信息进行比对;

 

Shiro认证过程:

1、创建SecurityManager

2、主体提交认证;

3、SecurityManager认证;

4、Authenticator认证;

5、Realm认证;

 

代码实现:

1、pom中添加依赖

<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<!-- aop -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.5</version>
		</dependency>
		
		<!-- shiro -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.4.0</version>
		</dependency>
		
		<!-- redis -->
		<dependency>
		    <groupId>org.springframework.data</groupId>
		    <artifactId>spring-data-redis</artifactId>
		    <version>1.7.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.8.1</version>
		</dependency>

 

2、web.xml中配置shiro拦截器

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
    version="2.5">  
  
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring/spring-context.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<!-- shiro权限校验 拦截器	 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<!-- 字符转码拦截器 -->
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<servlet>
		<servlet-name>dispatherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring/spring-servlet.xml</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	
  	
</web-app>  

 

3、自定义认证Realm,查询数据库认证信息

package com.huatech.support.shiro;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Component;

import com.huatech.core.domain.User;
import com.huatech.core.service.PermService;
import com.huatech.core.service.RoleService;
import com.huatech.core.service.UserService;

@Component
public class SystemAuthorizingRealm extends AuthorizingRealm {
	
	@Resource UserService userService;
	@Resource RoleService roleService;
	@Resource PermService permService;

	/**
	 * 角色、权限认证
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		String username = (String) principals.getPrimaryPrincipal();
		Set<String> roles = new HashSet<String>(roleService.findByUsername(username));
		Set<String> perms = new HashSet<String>();
		if(roles != null && roles.size() > 0) {
			perms = new HashSet<String>(permService.findByRoles(roles));
		}
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(roles);
		authorizationInfo.addStringPermissions(perms);
		return authorizationInfo;
	}

	/**
	 * 身份认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String username = (String) token.getPrincipal();
		User user = userService.findByUsername(username);
		if(user == null) {
			throw new UnauthenticatedException();
		}
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username, user.getPassword(), getName());
		authenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(username));
		return authenticationInfo;
	}
	
	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("md5");
		matcher.setHashIterations(1);
		super.setCredentialsMatcher(matcher);
	}
	
	
	@Override
	public String getName() {
		return this.getClass().getSimpleName();
	}

}

 

4、继承AbstractSessionDAO,实现Redis Session的增刪改查操作

 

package com.huatech.support.shiro;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;

/**
 * 继承AbstractSessionDAO,实现Redis Session的增刪改查操作
 * @author lh@erongdu.com
 * @since 2019-01-28
 *
 */
public class RedisSessionDao extends AbstractSessionDAO {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(RedisSessionDao.class);
	
	public static final String SESSION_PREFIX = "shiro_session:";
	public static final int DEFAILT_TIME_OUT = 30;
	@Resource RedisTemplate<String, Object> redisTemplate;
	//@Resource RedisUtil redisUtil;
	private int timeout = DEFAILT_TIME_OUT;
	
	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	@Override
	protected Serializable doCreate(Session session) {
		Serializable id = generateSessionId(session);
		LOGGER.debug("id:{}", id.toString());
		assignSessionId(session, id);//将session 和 sessionId捆绑在一起
		saveSession(session);
		return id;
	}
	
	public void update(Session session) throws UnknownSessionException {
		LOGGER.debug("id:{}", session.getId().toString());
		saveSession(session);
	}

	public void delete(Session session) {
		LOGGER.debug("id:{}", session.getId().toString());
		if(session == null || session.getId() == null){
			return;
		}
		redisTemplate.delete(getKey(session.getId()));
	}
	
	public Collection<Session> getActiveSessions() {
		 Set<String> keys = keys();
		 Set<Session> sessions = new HashSet<Session>();
		 if(keys.size() == 0){
			 return sessions;
		 }
		 for (String id : keys) {
			 Session _session = getSession(id);
			 if(_session == null){
				 continue;
			 }
			 sessions.add(_session);			 
		 }		 
		return sessions;
	}

	@Override
	protected Session doReadSession(Serializable sessionId) {
		if(sessionId == null){
			return null;
		}
		LOGGER.debug("id:{}", sessionId.toString());
		return getSession(sessionId);
	}
	
	private static String getKey(Serializable id){
		return SESSION_PREFIX + id.toString();
	}

	private void saveSession(Session session){
		if(session != null && session.getId() != null){
			Serializable id = session.getId();
			redisTemplate.opsForValue().set(getKey(id), session, timeout, TimeUnit.MINUTES);
		}
	}
	
	private Session getSession(Serializable id){
		return (Session)redisTemplate.boundValueOps(getKey(id)).get();
	}
	
	private Set<String> keys(){		  
    	return redisTemplate.execute(new RedisCallback<Set<String>>() {
			public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
				Set<String> binaryKeys = new HashSet<String>();
    	        Cursor<byte[]> cursor = connection.scan( new ScanOptions.ScanOptionsBuilder().match(SESSION_PREFIX + "*").count(1000).build());
    	        while (cursor.hasNext()) {    	        	
    	            binaryKeys.add(new String(cursor.next()));
    	        }
    	        connection.close();
    	        return binaryKeys;
			}
    	});    
	}
	 
}

 

5、实现用户角色、权限缓存管理

 

package com.huatech.support.shiro;

import java.util.Collection;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;

import com.alibaba.fastjson.JSONObject;

/**
 * 实现用户角色、权限缓存管理
 * @author lh@erongdu.com
 *
 */
public class RedisCacheManager implements CacheManager {
	
	@Resource RedisTemplate<String, Object> redisTemplate;
	private static final Logger LOGGER = LoggerFactory.getLogger(RedisCacheManager.class);
	//@Resource RedisUtil redisUtil;
	
	@Override
	public <K, V> Cache<K, V> getCache(String arg0) throws CacheException {
		return new RedisCache<K, V>();
	}
	
	class RedisCache<K, V> implements Cache<K, V>{

		private static final String CACHE_KEY = "redis-cache";
		
		@Override
		public void clear() throws CacheException {
			redisTemplate.delete(CACHE_KEY);
		}

		private String toString(Object obj){
			if(obj instanceof String){
				return obj.toString();
			}else{
				return JSONObject.toJSONString(obj);
			}
		}

		@SuppressWarnings("unchecked")
		@Override
		public V get(K k) throws CacheException {
			LOGGER.info("get field:{}", toString(k));
			return (V)redisTemplate.boundHashOps(CACHE_KEY).get(k);
		}

		@SuppressWarnings("unchecked")
		@Override
		public Set<K> keys() {
			LOGGER.info("keys");
			return (Set<K>)redisTemplate.boundHashOps(CACHE_KEY).keys();
		}

		@Override
		public V put(K k, V v) throws CacheException {
			LOGGER.info("put field:{}, value:{}", toString(k), toString(v));
			redisTemplate.boundHashOps(CACHE_KEY).put(k, v);
			return v;
		}

		@Override
		public V remove(K k) throws CacheException {
			LOGGER.info("remove field:{}", toString(k));
			V v = get(k);
			redisTemplate.boundHashOps(CACHE_KEY).delete(k);
			return v;
		}

		@Override
		public int size() {
			int size = redisTemplate.boundHashOps(CACHE_KEY).size().intValue();
			LOGGER.info("size:{}", size);
			return size;
		}

		@SuppressWarnings("unchecked")
		@Override
		public Collection<V> values() {
			LOGGER.info("values");
			return (Collection<V>)redisTemplate.boundHashOps(CACHE_KEY).values();
		}
		
		public String getCacheKey() {
			return "RedisCache";
		}
		
	}

}

 

6、重写DefaultWebSessionManager的retrieveSession方法,防止一个接口重复读取redis的session

 

package com.huatech.support.shiro;

import java.io.Serializable;

import javax.servlet.ServletRequest;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 重写DefaultWebSessionManager的retrieveSession方法,防止一个接口重复读取redis的session
 * @author lh@erongdu.com
 *
 */
public class RedisSessionManager extends DefaultWebSessionManager {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(RedisSessionManager.class);
	
	@Override
	protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
		Serializable sessionId = getSessionId(sessionKey);
		ServletRequest request = null;
		if(sessionKey instanceof WebSessionKey){
			request = ((WebSessionKey)sessionKey).getServletRequest();			
		}
		Session session = null;
		if(request != null && sessionId != null){
			session =  (Session) request.getAttribute(sessionId.toString());
		}
		if(session != null){
			return session;
		}
		try{
			session = super.retrieveSession(sessionKey);
		}catch(UnknownSessionException e){
			LOGGER.error(e.getMessage());
		}
		if(request != null && sessionId != null && session != null){
			request.setAttribute(sessionId.toString(), session);			
		}
		
		return session;
	}
	
}

 

7、spirng-servlet配置,启用shiro注解

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context="http://www.springframework.org/schema/context"   
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
        
    <context:component-scan base-package="com.huatech.core.controller"/>  
    <mvc:annotation-driven >
    	<mvc:message-converters>
			<bean class="org.springframework.http.converter.StringHttpMessageConverter">
		    	<constructor-arg value="UTF-8" />
			</bean>
		</mvc:message-converters>
    </mvc:annotation-driven>  
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/views/" />  
        <property name="suffix" value=".jsp" />  
    </bean>      
    <mvc:resources mapping="/**" location="/"/>
    <aop:config proxy-target-class="true"/>
    
    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
	<bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
	
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
    	<property name="securityManager" ref="securityManager"/>
	</bean>
	
</beans>  

 

8、Shiro配置

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
	xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"   
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd  
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd" default-lazy-init="false">
    
    <!-- 安全认证过滤器 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="login.jsp"/>
		<property name="unauthorizedUrl" value="403.jsp"/>
		<property name="filterChainDefinitions">
			<value>
				/login.jsp = anon
				/doLogin = anon
				/rolesOr = rolesOr["admin","admin1"]
				/roleAll = roles["admin", "admin1"]
				/* = authc
			</value>
		</property>
		<property name="filters">
			<util:map>
				<entry key="rolesOr" value-ref="rolesOrFilter"/>
			</util:map>
		</property>
	</bean>
	
	<bean id="rolesOrFilter" class="com.huatech.support.shiro.RolesOrFilter"/>
	
	<!-- 定义Shiro安全管理配置 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="realm" />
		<property name="sessionManager" ref="sessionManager" />
		<property name="cacheManager" ref="cacheManager" />
		<property name="rememberMeManager" ref="rememberMeManager"/>
	</bean>
	
	<bean id="realm" class="com.huatech.support.shiro.SystemAuthorizingRealm"/>

	<bean id="sessionManager" class="com.huatech.support.shiro.RedisSessionManager">
		<property name="sessionDAO" ref="redisSessionDao"/>
	</bean>
	<!-- 用户会话 操作 -->
	<bean id="redisSessionDao" class="com.huatech.support.shiro.RedisSessionDao">
		<property name="timeout" value="${redis.session.timeout}"/>
	</bean>
	<!-- 用户角色、权限缓存管理 -->
	<bean id="cacheManager" class="com.huatech.support.shiro.RedisCacheManager">
	</bean>
	
	<!-- 记住我 -->
	<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
		<property name="cookie" ref="simpleCookie"/>
	</bean>	
	<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
		<property name="name" value="remeberMe"/>
	</bean>
	
    
</beans>  

 

9、Redis配置

 

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
	xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd" 
    default-lazy-init="false">
     
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxIdle" value="${redis.pool.maxIdle}" /> 
		<property name="maxTotal" value="${redis.pool.maxTotal}" />
		<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
	</bean>
 	<bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
         <property name="hostName" value="${redis.host}" />
         <property name="port" value="${redis.port}" />
         <property name="timeout" value="${redis.timeout}" />
         <property name="password" value="${redis.password}" />
         <property name="poolConfig" ref="jedisPoolConfig" />
 	</bean>
 	
 	<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
	<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" 
		p:connectionFactory-ref="jedisConnFactory" />	 
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
		p:connectionFactory-ref="jedisConnFactory" 
		p:keySerializer-ref="stringRedisSerializer" 
		p:hashKeySerializer-ref="stringRedisSerializer" />
 	
    
</beans>  

 

代码已全部上传到gitee,完整代码请参考:https://gitee.com/hualee/spring4-shiro-redis-demo

 

  • 大小: 665.6 KB
分享到:
评论

相关推荐

    SSM+shiro+redis

    spring+springmvc+mybatis+shiro+redis集成项目,rdis作为并发缓存工具,shiro权限管理,实现单点登录,同一个用户会别踢下线

    SpringMVC-Mybatis-Shiro-redis-master 权限集成缓存中实例

    本人提供这个Shiro + SpringMvc + Mybatis + Redis 的Demo 本着学习的态度,如果有欠缺和不足的地方,给予指正,并且多多包涵。 “去其糟粕取其精华”。如果觉得写的好的地方就给个赞,写的不好的地方,也请多多包涵...

    SpringAll_wuyouzhuguli.tar.gz

    Spring Boot Shiro在线会话管理 Spring Boot Shiro整合JWT 三、Spring Boot & Security教程 Spring Boot中开启Spring Security Spring Security自定义用户认证 Spring Security添加图形验证码 Spring Security添加...

    基于ssm+shiro+redis+nginx tomcat服务器集群管理项目源码+项目说明.zip

    redis:Nosql数据库,搭配shiro的会话管理功能将session存入redis中,实现tomcat多服务器集群的session共享 nginx:反向代理服务器,用来调度多台tomcat h2:内存数据库,用于测试 开发环境 ==== jdk...

    小白图书笔记本管理Java系统Vue + Spring Boot 项目实战

    5.Spring Data Redis 3.数据库 1.MySQL 2.Redis 第三部分是在前面的基础上,分析项目存在的不足,并对其进行由点及面的优化。 当简单的优化无法达到我们想要的目的时,就需要从架构层面进行整体的升级改造

    yan:使用Maven构建,整合Dubbo + Zookeeper + SpringMVC + Spring + MyBatis + Redis支持分布式的高效率便捷开发框架

    该项目是单核项目的升级版,支持分布式近期更新内容beta 1.0.1:添加spring-session + redis技术,用于解决负载均衡下会话共享问题beta 1.0.0:项目整体改造,升级为RPC架构。(注:若想查看非RPC版请移步至 ) beta...

    SpringBoot2.0前后端分离开发之用户身份认证实战 (后端实现)

    (2) 基于Session的认证模式 也主要介绍了三种核心、主流的认证模式,即基于原生Spring Session以及Session共享的认证模式、基于Shiro Session的认证模式、基于Shiro + Redis 的Session共享认证模式 即课程的整体...

    JAVA分布式快速开发平台

    ● 核心框架:Spring Framework 4.3.0 + Dubbo 2.5.3 ● 安全框架:Apache Shiro 1.2 ...● 会话管理:Spring-Session 1.3.0 ● 日志管理:SLF4J、Log4j2 ● 前端框架:Angular JS + Bootstrap + Jquery

    xmljava系统源码-SLPlat:SLPlat基于开源项目ibase4j调整而得的,专注于本科院校实践类课程的教学与考试服务的平台。该平台

    xml java系统源码 SLPlat项目简介 SLPlat基于开源项目ibase4j调整而得的,专注于本科院校实践类课程的教学与考试服务的平台 ...shiro实现redis分布式session同步,重启服务会话不丢失。 多系统交互:Dubbo,Active

    javaweb讯友网络相册源码

    4. Shiro安全框架实现用户认证、授权、会话管理。 5. 邮件发送、文件上传、图像处理等第三方接口集成。 6. Vue.js实现页面异步交互,增强用户体验。 7. 日期选择器、树形控件、富文本编辑器等插件开发与整合。 8. ...

    javaweb芝麻开门博客网源码

    4. Shiro安全框架实现用户认证、授权、会话管理。 5. Markdown编辑器集成,支持Markdown语法发表文章。 6. 七牛云存储集成,上传的文章图片存储到七牛云。 7. Vue.js实现页面异步交互,增强用户体验。 8. 文件上传、...

    javaweb校园管理系统源码

    4. Shiro安全框架实现用户认证、权限控制、会话管理。 5. 邮件发送、短信发送、二维码生成等第三方接口调用。 6. 页面交互使用Vue.js,增强用户体验。 7. 日期控件、树控件、富文本编辑器等插件开发与整合。 8. ...

    SpringMVC+mybatis-framework-bootstrap

    实际使用shiro的时候大部分都是和spring等框架结合使用,主要就是配置web.xml将shiro的filter和spring容器bean的filter关联起来,生命周期由servlet容器来控制,然后配置shiro的spring的xml文件,其中主要配置shiro...

    智能发票识别系统后台.zip

    使用shiro作为安全管理框架,通过其内置session实现安全登录,使用shiro注解完成权限管理。 算法端 使用Bag of Words + CNN完成票据分类,根据分类结果查询并获取相应的发票模板。 使用SIFT特征匹配和配准思路完成...

    单点登录源码

    Apache Shiro | 安全框架 | [http://shiro.apache.org/](http://shiro.apache.org/) Spring session | 分布式Session管理 | [http://projects.spring.io/spring-session/]...

    iBase4J分布式系统-其他

    核心框架:Sring boot + Spring Framework + Dubbo + ibase4j-common安全框架:Apache Shiro任务调度:Spring + Quartz持久层框架:MyBatis + MyBatis-Plus数据库连接池:Alibaba Druid缓存框架:Redis会话管理:...

    【MaxKey单点登录认证系统 v2.4.0 RC】企业级IAM身份管理和身份认证产品+RBAC权限管理.zip

    7、基于Java平台开发,采用Spring、MySQL、Tomcat、Apache Kafka、Redis等开源技术,支持微服务,扩展性强。 8、许可证 Apache License, Version 2.0,开源免费。 源码更新日志: MaxKey单点登录认证系统 更新v...

    Java-Web:整理一套java web知识体系,从java入门到框架应用等

    发简历找工作的时候,面试官回了一句话: nosql,redis,主从复制,集群,哨兵,redis的rdb和aof,以及集群中增加删除主从节点都会吗。我对于redis的认识仅限于缓存的使用上,其他的什么都不清楚。于是我对redis进行...

    javaiHRM人力资源管理系统项目实战视频教程

    基于Shiro+Redis的分布式session解决方案。  3.可商用的权限设计方案(提供菜单,按钮,超链接,API粒度的权限控制)。  4.完整的代码生成器教程。  5.采用JasperReport完成企业级PDF报表生成。

Global site tag (gtag.js) - Google Analytics