Shiro整合SSM项目

搭建好SSM项目

可参考SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)

添加相关依赖

<!-- shiro相关的依赖 -->
<dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-spring</artifactId>
	<version>1.2.3</version>
</dependency>
  <dependency>
	<groupId>org.apache.shiro</groupId>
	<artifactId>shiro-ehcache</artifactId>
	<version>1.2.3</version>
</dependency>

在web.xml文件中注册shiro过滤器

<?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"
	id="WebApp_ID" version="3.1">
	<display-name>SSM</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>default.jsp</welcome-file>
	</welcome-file-list>
	<!-- 这里配置Spring配置文件的位置,param-name是固定的, param-value是文件位置 这个配置可以省略,如果省略, 系统默认去/WEB-INF/目录下查找applicationContext.xml作为Spring的配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-*.xml</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- 注册SpringMVC的前端控制器 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-mvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<!-- 配置中文的编码方式 -->
	<filter>
		<filter-name>characterEncodingFilter</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>forceRequestEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- shiro过虑器,DelegatingFilterProxy通过代理模式将spring容器中的bean和filter关联起来 -->
	<filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
		<!-- 设置true由servlet容器控制filter的生命周期 -->
		<init-param>
			<param-name>targetFilterLifecycle</param-name>
			<param-value>true</param-value>
		</init-param>
		<!-- 设置spring容器filter的bean id,如果不设置则找与filter-name一致的bean -->
		<init-param>
			<param-name>targetBeanName</param-name>
			<param-value>shiro</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 防止静态资源文件被拦截 -->
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.jpg</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.png</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.css</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>default</servlet-name>
		<url-pattern>*.js</url-pattern>
	</servlet-mapping>
</web-app>

添加shiro的配置文件

注意shiro的配置可以添加在spring的配置文件中。但是为了便于管理我们再单独创建一个shiro的配置文件,里面的Schema还是spring的。

<?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:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		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.3.xsd">
	<!-- 定义凭证匹配器 -->
 	<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"
 	 id="credentialsMatcher">
 		<!-- 配置散列算法 -->
 		<property name="hashAlgorithmName" value="md5"/>
 		<!-- 配置散列次数 -->
 		<property name="hashIterations" value="1024"/>
 	</bean>
 	<!-- 注册自定义Realm -->
 	<bean class="com.yjn.realm.MyRealm" id="myRealm">
 		<!-- 配置凭证匹配器 -->
 		<property name="credentialsMatcher" ref="credentialsMatcher"/>
 	</bean>
 	<!-- 注册SecurityManager -->
 	<bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager">
 		<!-- 配置自定义Realm -->
 		<property name="realm" ref="myRealm"/>
 	</bean>
 	<!-- 注册ShiroFilterFactoryBean 注意id必须和web.xml中注册的targetBeanName的值一致 -->
 	<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" id="shiro">
 		<!-- 注册SecurityManager -->
 		<property name="securityManager" ref="securityManager"/>
 		<!-- 登录地址 如果用户请求的的地址是 login.do 那么会对该地址认证-->
 		<property name="loginUrl" value="/login.do"/>
 		<!-- 登录成功的跳转地址 -->
 		<property name="successUrl" value="/jsp/success.jsp"/>
 		<!-- 访问未授权的页面跳转的地址 -->
 		<property name="unauthorizedUrl" value="/jsp/refuse.jsp"/>
 		<!-- 设置 过滤器链 -->
 		<property name="filterChainDefinitions">
 			<value>
 				<!--加载顺序从上往下。
 					authc需要认证
 					anon可以匿名访问的资源
 				 -->
 				/login.do=authc
 				/login.jsp=anon
 				/**=authc
 			</value>
 		</property>
 	</bean>
</beans>

认证部分

创建自定义的Realm类

/**
 * 自定义的realm
 *
 */
public class MyRealm extends AuthorizingRealm{
    
    
	@Autowired
	private UserService userService;
	/**
	 * 认证的方法
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    
    
		// 获取登录的账号
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		String username = upToken.getUsername();
		System.out.println("登录提交的账号:"+username);
		// 去数据库中查询
		List<UserBean> list = userService.login(username);
		if(list == null || list.size() != 1){
    
    
			return null;
		}
		UserBean user = list.get(0);
		return new SimpleAuthenticationInfo(user.getUsername()
				, user.getPassword()
				, new SimpleByteSource(user.getSalt())
				, "abc");
	}
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
    
		// TODO Auto-generated method stub
		return null;
	}
}

LoginController测试

@Controller
public class LoginController {
    
    
	/**
	 * 在shiro中
	 *   本方法在realm认证失败后会执行
	 *   指定认证失败跳转的页面
	 * @return
	 */
	@RequestMapping("/login.do")
	public String login(Model model,HttpServletRequest request){
    
    
		Object ex = request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
		if(ex!= null) {
    
    
			System.out.println(ex.toString()+"----------------");
		}
		if(UnknownAccountException.class.getName().equals(ex)) {
    
    
			System.out.println("------账号不正确------->");
			request.setAttribute("msg", "账号不正确");
			return "redirect:/fail.jsp";
		}else if(IncorrectCredentialsException.class.getName().equals(ex)) {
    
    
			System.out.println("------密码不正确------->");
			request.setAttribute("msg", "密码不正确");
			return "redirect:/fail.jsp";
		}
		return "redirect:/success.jsp";
	}
}

在这里插入图片描述

授权部分

在自定义的Realm类中添加授权处理的方法

	/**
	 * 授权处理
	 * 形参中的获取的身份信息和 认证方法SimpleAuthenticationInfo的第一个参数有关
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    
    
		String userName = (String) principals.getPrimaryPrincipal();
		System.out.println("授权操作:"+userName);
		// 根据认证信息去数据库中查询对应的角色和权限
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addRole("stu");
		info.addRole("admin");
		info.addStringPermission("user:create");
		return info;
	}

在SpringMVC的配置文件中开启Shiro注解

	<!-- 开启Shiro注解 -->
	<aop:config proxy-target-class="true"></aop:config>
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager"/>
	</bean>

注解权限验证

	@RequiresRoles("admin")//验证角色
	@RequiresPermissions("user:update")//验证权限
	@RequestMapping("/query2")
	public String query2(){
    
    
		System.out.println("----query2----");
		return "/success.jsp";
	}

指定没有权限访问的跳转地址

虽然配置了此设置,但是在使用注解的形式下,未授权的情况下还是不会跳转,此时我们需要在SpringMVC中添加对应的拦截器处理

	<!-- shiro为集成springMvc 拦截异常 -->
	<bean
		class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 这里你可以根据需要定义N多个错误异常转发 -->
				<prop key="org.apache.shiro.authz.UnauthorizedException">refuse.jsp</prop>
				<prop key="org.apache.shiro.authz.UnauthenticatedException">login.jsp</prop>
				<prop key="java.lang.IllegalArgumentException">fail.jsp</prop> 
				<prop key="java.lang.Exception">error.jsp</prop>
			</props>
		</property>
	</bean>

jsp标签验证

引入标签库

<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro" %>

标签验证

	<h1>HOME页面</h1>
	<h2>导航栏</h2>
	<shiro:hasRole name="admin">
		<a href="#">用户管理</a><br>
	</shiro:hasRole>
	<shiro:hasRole name="stu">
		<a href="#">角色管理</a><br>
	</shiro:hasRole>
	<shiro:hasPermission name="user:create">
		<a href="#">菜单管理</a><br>
	</shiro:hasPermission>
	<shiro:hasPermission name="dept:create">
		<a href="#">部门管理</a><br>
	</shiro:hasPermission>
	<shiro:hasAnyRoles name="admin,a1,a2,a3">
		<a href="#">xxxx</a><br>
	</shiro:hasAnyRoles>
	<shiro:authenticated>
		<label><shiro:principal ></shiro:principal>】
		登录了。。。
		</label><br>
	</shiro:authenticated>
	<shiro:guest>
		<label>游客</label><br>
	</shiro:guest>
	<shiro:lacksRole name="stu">
		<label>当前登录的账号没有stu1这个角色</label><br>
	</shiro:lacksRole>
	<shiro:user>
		用户登录成功!
	</shiro:user>

shiro标签说明

标签 说明
<shiro:authenticated> 表示已认证通过,只有已通过用户认证,而不是通过remenber me浏览,才能看到标签里的内容
<shiro:guest> 只有没登录过,以游客的身份浏览才能看到标签里的内容
<shiro:hasRole name=""> 表示拥有某一角色,name属性填角色名
<shiro:hasAnyRoles name=""> 表示拥有多角色中任意一角色
<shiro:hasPermission name=""> 表示拥有某一权限
<shiro:lacksRole name=""> 表示不拥有某一角色
<shiro:lacksPermission name=""> 表示不拥有某一权限
<shiro:notAuthenticated> 表示没有通过认证
<shiro:principal> 表示用户的身份
<shiro:user> 表示已登录

猜你喜欢

转载自blog.csdn.net/WA_MC/article/details/113715872