Shiro的授权整合SSH

版权声明:本文为博主原创文章,版权归原作者小思所有,转载或者引用本文内容请注明来源及原作者,https://blog.csdn.net/zeal9s/ https://blog.csdn.net/zeal9s/article/details/83385811

完整项目代码:https://download.csdn.net/download/zeal9s/10744751
1.新建或者导入一个SSH项目
项目模块图如下
在这里插入图片描述

在这里插入图片描述
2.导入shiro依赖到pom.xml
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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>SSH_02</groupId>
	<artifactId>SSH_02</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SSH_02 Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<properties>
		<spring.version>4.3.10.RELEASE</spring.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.12</version>
			<scope>test</scope>
		</dependency>
		<!--引入servlet依赖:解决jsp页面报错 -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.0-b07</version>
			<scope>provided</scope>
		</dependency>

		<!-- 引入struts2依赖 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.3.33</version>
		</dependency>

		<!-- 引入Spring核心库 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!--引入struts2整合Spring的依赖 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>2.5.12</version>
		</dependency>
		<!--引入log4j的依赖:如果没有这个包apache启动就会报错 -->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
		<!-- 加入hibernate核心库 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.2.10.Final</version>
		</dependency>
		<!-- MySQL -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.43</version>
		</dependency>
		<!-- 引入c3p0数据库连接池依赖 -->
		<dependency>
			<groupId>com.mchange</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.5.2</version>
		</dependency>
		<!--引入Spring整合Hibernate依赖 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!--引入 spring 的AspectJ依赖:解析事务切点 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<!--引入shiro的核心依赖 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-core</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!--引入shiro的web依赖 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-web</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!--引入shiro整合spring -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.3.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>SSH_02</finalName>
	</build>
</project>

3.新建shiro包和MyRealm类
MyRealm.java

package com.zs.shiro;

import java.util.ArrayList;
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;

public class MyRealm extends AuthorizingRealm {

	// 授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		//获取认证完成之后的用户名
		String uname=(String) principals.getPrimaryPrincipal();
		//模拟通过用户名查询的角色
		List<String> roles=new ArrayList<String>();
		roles.add("son");
		//模拟通过角色查询角色所拥有的权限
		List<String> behaves=new ArrayList<String>();
		behaves.add("add");
		//认证成功之后才能进行授权
		SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
		//将查询到的角色赋予用户
		info.addRoles(roles);
		//将查询到的权限赋予给角色
		info.addStringPermissions(behaves);
		//将授权信息返回给测试类TestShiro
		return info;
	}

	// 认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 创建认证的令牌
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		// 用户名输入的名称和密码
		String uname = usernamePasswordToken.getUsername();
		String pwd = new String(usernamePasswordToken.getPassword());
		// 数据库查询出的用户名密码
		String dbpwd = "1234";
		System.out.println("用户名输入的名称和密码\t" + uname + "\t" + pwd);
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(uname, dbpwd, getName());
		return info;
	}

}

4.新建applicationContext-shiro.xml
applicationContext-shiro.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
	<!--shiro的过滤器 -->
	<bean id="shiroFilterFactoryBean"
		class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!--配置shiro过滤器的安全管理工厂 -->
		<property name="securityManager" ref="securityManager"></property>
		<!--配置登录的页面,此页面不需要认证 -->
		<property name="loginUrl" value="/login.jsp"></property>
		<!--认证成功之后才能进入的页面 -->
		<property name="successUrl" value="/success.jsp"></property>
		<!--过滤器继续自行的操作 -->
		<property name="filterChainDefinitions">
		     <value>
		     <!--配置匿名用户才能访问的页面  -->
		     /login.jsp*=anon
		     <!--配置认证完成的用户才能访问的页面  -->
		     /success.jsp*=authc
		     <!--配置拥有某个角色才能进入的页面  -->
		     /father.jsp*=roles[father]
		     /son.jsp*=roles[son]
		     </value>
		</property>
		<!--配置没有角色访问时跳转的页面  -->
		<property name="unauthorizedUrl" value="/nopremission.jsp"></property>
	</bean>



	<!--Spring产生安全管理者对象 -->
	<bean id="securityManager"
		class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="myRealm"></property>
	</bean>

	<!--spring产生MyRealm对象 -->
	<bean id="myRealm" class="com.zs.shiro.MyRealm"></bean>


</beans>

5.在web.xml添加shiro在spring的过滤器
web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
	<display-name>Archetype Created Web Application</display-name>
	<!--struts2和Spring整合时 运行时web容器加载applicationContext.xml -->
	<!--1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 
		和 <context-param></context-param> 2.紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文. 
		3.容器将<context-param></context-param>转化为键值对,并交给ServletContext. 4.容器创建<listener></listener>中的类实例,即创建监听. 
		5.在监听中会有contextInitialized(ServletContextEvent args)初始化方法,在这个方法中获得ServletContext 
		= ServletContextEvent.getServletContext(); context-param的值 = ServletContext.getInitParameter("context-param的键"); 
		6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早. 
		换句话说,这个时候,你对<context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行. -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext-*.xml</param-value>
	</context-param>
	<!--配置spring中shiro的过滤器-->
	<filter>
	    <filter-name>shiroFilterFactoryBean</filter-name>
	    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<!--struts2核心的过滤器 -->
	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	
	<filter-mapping>
	    <filter-name>shiroFilterFactoryBean</filter-name>
	    <url-pattern>/*</url-pattern>
	</filter-mapping>
	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>*.action</url-pattern>
	</filter-mapping>
	<!--web加载spring的监听器 -->
	<listener>
	    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>

6.新建login.jsp和success.jsp、father.jsp、son.jsp、nopremission.jsp
login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="testAction_login.action" method="post">
用户名:<input type="text" name="uname"><br>
密    码:<input type="password" name="pwd"><br>
<input type="submit" value="登录">
</form>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://shiro.apache.org/tags"  prefix="shiro"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
认证成功之后才能进入的页面!
<p>
<!--查看登录名  -->
欢迎<shiro:principal></shiro:principal>登录!
<p>
<!--谁拥有哪个角色,下面的页面就显示哪些  -->
<shiro:hasRole name="son">
<a href="son.jsp">son拥有的页面</a>
</shiro:hasRole>
<shiro:hasRole name="father">
<a href="father.jsp">father拥有的页面</a>
</shiro:hasRole>
</body>
</html>

son.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
拥有son角色才能进入的页面!!!!
</body>
</html>

father.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
拥有father角色才能进入的页面!!!!
</body>
</html>

7.新建TestAction,并且在spring注入属性和在struts里面配置action
TestAction

package com.ssh.action;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 
 * @ClassName: TestAction
 * @Description:测试页面收集的用户名和密码认证是否通过
 * @author 小思
 * @date 2018年8月29日 下午2:43:48
 *
 */
public class TestAction extends ActionSupport {
	private SecurityManager securityManager;
	// 收集login.jsp页面的用户名和密码
	private String uname;
	private String pwd;

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public SecurityManager getSecurityManager() {
		return securityManager;
	}

	public void setSecurityManager(SecurityManager securityManager) {
		this.securityManager = securityManager;
	}

	// 登录
	public String login() {
		// 利用帮助类将安全管理者添加到当前的安全管理环境中
		SecurityUtils.setSecurityManager(securityManager);
		// 获取安全管理的项目
		Subject subject = SecurityUtils.getSubject();
		// 定义返回类型
		String ret = "SUCCESS";
		// 创建保存用户用户名和密码的令牌(用户名和密码是页面收集的,是用户在页面上填写的)
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(uname, pwd);
		// 保存认证结果
		boolean authenticated = false;
		try {
			subject.login(usernamePasswordToken);
			authenticated = subject.isAuthenticated();
		} catch (Exception e) {
			// 认证失败,则返回原登录页面
			ret = "login";
		}
		System.out.println("认证结果:" + authenticated);

		// 授权过程之后的使用
		// 判断用户是否具有某个角色
		boolean role = subject.hasRole("son");
		System.out.println("用户具有son角色吗?" + role);
		// 角色是否拥有某个权限
		boolean behave = subject.isPermitted("add");
		System.out.println("son具有add权限吗?" + behave);
		// 角色是否拥有某个权限
		boolean behaves = subject.isPermittedAll("update", "query");
		System.out.println("son具有update、query权限吗?" + behaves);
        return ret;
	}

}

8.运行结果
运行login.jsp
(1)使用admin,1234登录,则是跳转到success.jsp,此页面显示son该有的页面
在这里插入图片描述
(2)使用admin登录之后,强行访问father.jsp则会跳转到nopremission.jsp
在这里插入图片描述
(3)不登录,直接访问其他页面则是跳转到login.jsp

备注:(1)整个项目需要在有网的情况运行,不然会报错
在这里插入图片描述
(2)如果要精确到权限,则在success.jsp添加shiro的自定义标签中的

在这里插入图片描述

说在最后的话:编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

猜你喜欢

转载自blog.csdn.net/zeal9s/article/details/83385811
今日推荐