跟我学Shiro实践-整合Spring
仅作为个人代码翻阅记录
maven依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- 日志SLF4j 接口 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.12</version> </dependency> <!--实现slf4j接口并整合 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.1</version> </dependency> <!-- Shiro安全框架 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.0</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- 数据源dataSource --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency> <!-- Spring 集成shiro --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- Shiro --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency> <!-- Shiro注解 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <!-- Redis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- jsp依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> </dependencies>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>shiro</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-*.xml</param-value> </context-param> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>登录界面</title> </head> <body> <form action="subLogin" method="post"> 用户名:<input type="text" name="username"><br> 密 码:<input type="password" name="password"><br> 记住我:<input type="checkbox" name="rememberMe"><br> <input type="submit" value="登录"> </form> </body> </html>
UserController
@Controller public class UserController { @RequestMapping( value="/subLogin", method=RequestMethod.POST, produces="application/json;charset=utf-8") @ResponseBody public String subLogin(User user) { Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword()); try { token.setRememberMe(user.isRememberMe()); subject.login(token); } catch (Exception e) { return e.getMessage(); } // 编码方式判断是否具有管理员身份 if (subject.hasRole("admin")) { return "有admin权限"; } return "无admin权限"; } //通过注解设置角色权限为admin才可访问 @RequiresRoles("admin") @RequestMapping(value="/testRole", method=RequestMethod.GET) @ResponseBody public String testRole() { return "test role success"; } /** * 通过在service.xml配置访问权限 */ @RequestMapping(value="/testRoles", method=RequestMethod.GET) @ResponseBody public String testRoles() { return "test roles success"; } @RequestMapping(value="/testRoles1", method=RequestMethod.GET) @ResponseBody public String testRoles1() { return "test roles1 success"; } @RequestMapping(value="/testPerms", method=RequestMethod.GET) @ResponseBody public String testPerms() { return "test roles success"; } @RequestMapping(value="/testPerms1", method=RequestMethod.GET) @ResponseBody public String testPerms1() { return "test roles1 success"; } }
spring.xml
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <import resource="spring-dao.xml" /> <context:component-scan base-package="net.laoyeye.controller" /> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="login.html"></property> <property name="unauthorizedUrl" value="403.html"></property> <property name="filterChainDefinitions"> <value> /login.html = anon /test = anon /test.do = anon /testRoles = roles["admin","admin1"] /testRoles1 = rolesOr["admin","admin1"] /subLogin = anon /* = authc </value> </property> <property name="filters"> <map> <entry key="rolesOr" value-ref="rolesOrFilter" /> </map> </property> </bean> <!-- 自定义filter --> <bean id="rolesOrFilter" class="net.laoyeye.filter.RolesOrFilter" /> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="realm"></property> </bean> <bean id="realm" class="net.laoyeye.realm.CustomRealm"> <property name="credentialsMatcher" ref="credentialsMatcher" ></property> </bean> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5" /> <property name="hashIterations" value="1" /> </bean> </beans>
springmvc.xml 注解生效
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <context:component-scan base-package="net.laoyeye.controller"></context:component-scan> <mvc:annotation-driven /> <!-- 排除静态文件 --> <mvc:resources location="/" mapping="/*" /> <!-- 开启AOP --> <aop:config proxy-target-class="true" /> <!-- 保证 Shiro内部生命周期 --> <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"></bean> <!-- 开启Shiro授权生效 --> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"></bean> </beans>
自定义Filter实现
/** * 自定义权限过滤器 * 也可以自定义其他过滤器 * @author Administrator * */ public class RolesOrFilter extends AuthorizationFilter { @Override protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object object) throws Exception { Subject subject = getSubject(req, resp); String[] roles = (String[]) object; if (roles == null || roles.length == 0) { return true; } for (String role : roles) { if (subject.hasRole(role)) { return true; } } return false; } }
自定义sessionManage
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; /** * Create by laoyeye **/ public class CustomSessionManage extends DefaultWebSessionManager { @Override protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException { Serializable sessionId = getSessionId(sessionKey); ServletRequest request = null; if(sessionKey instanceof WebSessionKey) { request = ((WebSessionKey)sessionKey).getServletRequest(); } if(request != null && sessionId != null) { Session session = (Session) request.getAttribute(sessionId.toString()); if(session != null) { return session; } } Session session = super.retrieveSession(sessionKey); if(request != null && sessionId != null) { request.setAttribute(sessionId.toString(), session); } return session; } }
自定义cacheManage
public class RedisCacheManager implements CacheManager { @Resource private RedisCache redisCache; @Override public <K, V> Cache<K, V> getCache(String s) throws CacheException { return redisCache; } }
重写后的spring.xml
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="login.html"></property><!-- 没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面 --> <property name="unauthorizedUrl" value="403.html"></property><!-- 没有权限默认跳转的页面 --> <property name="filterChainDefinitions"> <value><!-- 自上到下 --><!-- anon:表示可以匿名使用。 authc:表示需要认证(登录)才能使用,没有参数. roles["admin,guest"],每个参数通过才算通过,user表示必须存在用户 --> /login.html = anon /subLogin = anon /testRoles = roles["admin"] /testRoles1 = rolesOr["admin","admin1"] /testPerms = perms["user:delete"] /testPerms1 = perms["user:delete","user:updata"] /* = authc </value> </property> <property name="filters"> <map> <entry key="rolesOr" value-ref="rolesOrFilter" /> </map> </property> </bean> <!-- 自定义权限filter --> <bean id="rolesOrFilter" class="net.laoyeye.filter.RolesOrFilter" /> <!-- 创建SecurityManager对象 --> <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="cookieRememberMeManager" /> </bean> <!-- 自定义Realm --> <bean id="realm" class="net.laoyeye.realm.CustomRealm"> <property name="credentialsMatcher" ref="credentialsMatcher" ></property> </bean> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="md5" /> <property name="hashIterations" value="1" /> </bean> <!-- 自定义SessionManager --> <bean class="net.laoyeye.session.CustomSessionManage" id="sessionManager"> <property name="sessionDAO" ref="redisSessionDao"></property> </bean> <bean class="net.laoyeye.session.RedisSessionDao" id="redisSessionDao"></bean> <bean class="net.laoyeye.cache.RedisCacheManager" id="cacheManager"></bean> <!-- 自动登录 --> <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager" id="cookieRememberMeManager"> <property name="cookie" ref="cookie"></property> </bean> <bean class="org.apache.shiro.web.servlet.SimpleCookie" id="cookie"> <constructor-arg name="name" value="rememberMe" /> <property name="maxAge" value="20000000" /> </bean> </beans>
❤本博客只适用于研究学习为目的,大多为学习笔记,如有错误欢迎指正,如有误导敬请谅解(本人尽力保证90%的验证和10%的猜想)。
❤如果这篇文章对你有一点点的帮助请给一份推荐! 谢谢!你们的鼓励是我继续前进的动力。

浙公网安备 33010602011771号