Springmvc+Shiro实战
原文链接:http://blog.csdn.net/qq_37936542/article/details/79010449
springmvc+shiro实现系统粗细粒度的权限管理步骤:
1:表格设计
2:配置maven依赖
3:web.xml配置shiro过滤器
4:web.xml引入applicationContext-shiro.xml的配置文件
5:配置applicationContext-shiro.xml配置文件
6:配置shiro缓存文件
7:自定义realm实现用户认证和授权
8:实现登录逻辑
9:页面控制权限
一:表格设计(一个用户对应一个系统角色,一个系统角色具有多个操作权限)
二:导入相关依赖 pom.xml
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>debo</groupId>
- <artifactId>debo</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>war</packaging>
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring.version>4.3.6.RELEASE</spring.version>
- </properties>
- <dependencies>
- <!-- 导入java ee jar 包 -->
- <dependency>
- <groupId>javax</groupId>
- <artifactId>javaee-api</artifactId>
- <version>6.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax</groupId>
- <artifactId>javaee-web-api</artifactId>
- <version>6.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>jstl</artifactId>
- <version>1.2</version>
- </dependency>
- <!-- spring框架包 start -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</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-oxm</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-tx</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-aop</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-expression</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-orm</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</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-websocket</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjrt</artifactId>
- <version>1.8.10</version>
- </dependency>
- <dependency>
- <groupId>org.aspectj</groupId>
- <artifactId>aspectjweaver</artifactId>
- <version>1.6.12</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-messaging</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <!-- spring框架包 end -->
- <!-- mybatis框架包 start -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.3.0</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.0</version>
- </dependency>
- <!-- mybatis框架包 end -->
- <!-- shiro -->
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-core</artifactId>
- <version>1.3.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-web</artifactId>
- <version>1.3.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-spring</artifactId>
- <version>1.3.2</version>
- </dependency>
- <dependency>
- <groupId>org.apache.shiro</groupId>
- <artifactId>shiro-ehcache</artifactId>
- <version>1.3.2</version>
- </dependency>
- <!-- log4j -->
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.16</version>
- </dependency>
- <!-- lang3 -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
- <version>3.6</version>
- </dependency>
- <!-- dhcp连接池 -->
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <version>1.4</version>
- </dependency>
- <!-- MySql -->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.38</version>
- </dependency>
- <!-- poi -->
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi</artifactId>
- <version>3.17</version>
- </dependency>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml-schemas</artifactId>
- <version>3.17</version>
- </dependency>
- <dependency>
- <groupId>org.apache.poi</groupId>
- <artifactId>poi-ooxml</artifactId>
- <version>3.17</version>
- </dependency>
- <!-- jack json -->
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>2.7.3</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>2.7.3</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>2.7.3</version>
- </dependency>
- <!-- commons-io -->
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- </dependency>
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <version>1.3.1</version>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.3.2</version>
- <configuration>
- <source>1.7</source>
- <target>1.7</target>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-war-plugin</artifactId>
- <version>2.2</version>
- <configuration>
- <version>3.1</version>
- <failOnMissingWebXml>false</failOnMissingWebXml>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
三:web.xml配置shiro拦截器
- <!-- 这里的filter-name 要和spring 的applicationContext-shiro.xml 里的
- g.apache.shiro.spring.web.ShiroFilterFactoryBean 的bean name 相同 -->
- <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>
- <!-- springmvc控制器 -->
- <servlet>
- <servlet-name>dispatcherServlet</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!-- 加载springmvc配置文件 -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:spring/springmvc-servlet.xml,classpath:spring/applicationContext*.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcherServlet</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
配置文件目录结构:
五:配置applicationContext-shiro.xml文件
- <!-- 配置shiro安全管理器 -->
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="shiroDbRealm"/>
- <!-- 配置缓存 -->
- <property name="cacheManager" ref="cacheManager"/>
- </bean>
- <!-- 自定义的Realm:用于用户的认证和授权 -->
- <bean id="shiroDbRealm" class="com.debo.login.controller.ShiroDbRealm"/>
- <!-- 此bean要被web.xml引用,和web.xml中的filtername同名 -->
- <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="/noPromission.jsp" /> <!-- 没有授权返回地址 -->
- <property name="filterChainDefinitions">
- <value> <!-- **代表任意子目录 -->
- /css/** = anon
- /img/** = anon
- /js/** = anon
- /jsp/** = user
- /web/** = anon
- /**/**=user
- </value>
- </property>
- </bean>
- <!-- 用户授权/认证信息Cache, 采用EhCache 缓存 -->
- <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
- </bean>
- <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
六:配置ehcache-shiro.xml文件
- <ehcache updateCheck="false" name="shiroCache">
- <defaultCache
- maxElementsInMemory="10000"
- eternal="false"
- timeToIdleSeconds="120"
- timeToLiveSeconds="120"
- overflowToDisk="false"
- diskPersistent="false"
- diskExpiryThreadIntervalSeconds="120"
- />
- </ehcache>
七:自定义realm AuthRealm
- package com.debo.login.controller;
- import java.util.List;
- 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.UsernamePasswordToken;
- import org.apache.shiro.authz.AuthorizationInfo;
- import org.apache.shiro.authz.SimpleAuthorizationInfo;
- import org.apache.shiro.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.springframework.beans.factory.annotation.Autowired;
- import com.debo.security.pojo.User;
- import com.debo.security.service.RoleService;
- import com.debo.security.service.UserService;
- public class ShiroDbRealm extends AuthorizingRealm {
- @Autowired
- private UserService userService;
- @Autowired
- private RoleService roleService;
- /**
- * shiro认证
- */
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(
- AuthenticationToken authcToken) throws AuthenticationException {
- UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
- String loginName = token.getUsername();
- if (loginName != null && !"".equals(loginName)) {
- // 通過登录名获取用户
- User user = userService.getUserByLoginName(loginName);
- if (user != null) {
- // 如果身份认证验证成功,返回一个AuthenticationInfo实现
- return new SimpleAuthenticationInfo(user.getLoginName(),
- user.getPassword(), getName());
- }
- }
- return null;
- }
- /**
- * shiro授权
- */
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(
- PrincipalCollection principals) {
- String loginName = (String) getAvailablePrincipal(principals); // 使用Shiro提供的方法获取用户名称
- if (loginName != null) {
- String roleId = userService.getRoleIdByLoginName(loginName);
- // 获取用户的权限
- List<String> permTokens = roleService.getPermTokens(roleId);
- SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
- if (roleId != null) {
- info.addRole(roleId); // 加入用户角色
- }
- if (permTokens != null) {
- info.addStringPermissions(permTokens); // 加入用户许可标记
- }
- return info;
- }
- return null;
- }
- }
八:书写登录逻辑
- package com.debo.login.controller;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpSession;
- import org.apache.shiro.SecurityUtils;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.UsernamePasswordToken;
- import org.apache.shiro.subject.Subject;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.context.ContextLoader;
- import org.springframework.web.context.WebApplicationContext;
- import org.springframework.web.servlet.mvc.support.RedirectAttributes;
- import com.debo.company.service.CompanyService;
- import com.debo.develop.service.MenuService;
- import com.debo.security.pojo.User;
- import com.debo.security.service.UserService;
- @Controller
- @RequestMapping("/login")
- public class LoginController {
- @Autowired
- private MenuService menuService;
- @Autowired
- private UserService userService;
- @Autowired
- private CompanyService companyService;
- @RequestMapping(method = {RequestMethod.GET})
- public String login(HttpServletRequest request) {
- System.out.println("欢迎登陆!……");
- return "/login";
- }
- @RequestMapping(method = {RequestMethod.POST})
- public String loginPost(User user, RedirectAttributes redirectAttributes, HttpServletRequest request) {
- Subject currentUser = SecurityUtils.getSubject();
- UsernamePasswordToken token = new UsernamePasswordToken(user.getLoginName(), user.getPassword(), user.isRememberMe());
- try {
- //用户认证
- currentUser.login(token);
- } catch (AuthenticationException e) {
- System.out.println(e);
- redirectAttributes.addFlashAttribute("message", "用户名或密码错误!");
- return "redirect:/login";
- }
- if (currentUser.isAuthenticated()) {
- //登录成功,保存用户相关信息
- sessionHandle(user, request);
- //跳转成功页面
- return "redirect:/index";
- } else {
- redirectAttributes.addFlashAttribute("message", "用户名或密码错误!");
- return "redirect:/login";
- }
- }
- private void sessionHandle(User user, HttpServletRequest request) {
- HttpSession session = request.getSession();
- User loginUser = userService.getUserByLoginName(user.getLoginName());
- if(loginUser != null){
- session.setAttribute("companyId", loginUser.getCompanyId());
- session.setAttribute("username", loginUser.getNickName());
- session.setAttribute("userId", loginUser.getId());
- }
- //menuService.updateMenuInSession(request);
- }
- }
九:jsp页面控制权限
- <%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%><!-- 导入标签库 -->
- <!-- 如果用户有deleteUser的权限 则显示删除 -->
- <shiro:hasPermission name="deleteUser">
- <span id="delete" onclick="delete(this)">删除</span>
- </shiro:hasPermission>
文末福利:
福利一:前端,Java,产品经理,微信小程序,Python等8G资源合集大放送:https://www.jianshu.com/p/e8197d4d9880
福利二:微信小程序入门与实战全套详细视频教程
领取方式:
如果需要学习视频,欢迎关注 【编程微刊】微信公众号,回复【领取资源】一键领取以下所有干货资源,获取更多有用技术干货、文档资料。所有文档会持续更新,欢迎关注一起成长!