SSM_Shiro 整合


SSM初始框架(非MAVEN)


下载下来的使用的数据库是sql server.

如需更改请修改目录下config.properties

几种常见的数据库配置:

# Properties file with JDBC-related settings.
##########
# HSQLDB #
##########
#jdbc.driverClassName=org.hsqldb.jdbcDriver
#jdbc.url=jdbc:hsqldb:hsql://localhost:9001/bookstore
#jdbc.username=
#jdbc.password=
###########
# MySQL 5 #
###########
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=GBK
jdbc.username=
jdbc.password=
##############
# PostgreSQL #
##############
#jdbc.driverClassName=org.postgresql.Driver
#jdbc.url=jdbc:postgresql://localhost/bookstore
#jdbc.username=
#jdbc.password=
##########
# Oracle #
##########
#jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
#jdbc.url=jdbc:oracle:thin:@192.168.1.250:1521:devdb
#jdbc.username=
#jdbc.password=
#############################
# MS SQL Server 2000 (JTDS) #
#############################
#jdbc.driverClassName=net.sourceforge.jtds.jdbc.Driver
#jdbc.url=jdbc:jtds:sqlserver://localhost:1433/bookstore
#jdbc.username=
#jdbc.password=
##################################
# MS SQL Server 2000 (Microsoft) #
##################################
#jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
#jdbc.url=jdbc:sqlserver://192.168.1.130:1433;database=ahos
#jdbc.username=
#jdbc.password=
########
# ODBC #
########
#jdbc.driverClassName=sun.jdbc.odbc.JdbcOdbcDriver
#jdbc.url=jdbc:odbc:bookstore
#jdbc.username=
#jdbc.password=
浏览器请求:http://localhost:8080/SSM/?id=1 会显示id为1的用户姓名;

下面开始融合shiro:

jar包:shiro-all : 官网下载,直接下载shiro-all即可;

ehcache.jar 官网下载

1:web.xml中添加代码:

	<filter>
		<description>shiro 权限拦截</description>
		<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>

2:在src目录下添加spring-shiro.xml,必须以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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	<!-- 启用shrio授权注解拦截方式 -->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 装配 securityManager -->
		<property name="securityManager" ref="securityManager" />
		<!-- 配置登陆页面 -->
		<property name="loginUrl" value="/" />
		<!-- 登陆成功后的一面 -->
		<property name="successUrl" value="html/management.html" />
		<property name="unauthorizedUrl" value="/unauthorized" />
		<!--自定义的Roles Filter-->
		<property name="filters">  
            <map>  
                <entry key="anyRoles" value-ref="anyRoles"/> 
            </map>  
        </property>
		<!-- 具体配置需要拦截哪些 URL, 以及访问对应的 URL 时使用 Shiro 的什么 Filter 进行拦截. -->
		<property name="filterChainDefinitions" >
			 <value>
				/management = authc
				/authCode = anon
				/css/** = anon
				/js/** = anon
				/assets/** = anon
				/do/** = anon
				/admin/* = anyRoles[admin,super_admin]
				/admin/super/* = roles[super_admin]
				/users/* = anyRoles[super_admin,admin,users]
				*/logout = logout
				
				/**=authc 
			</value>
		</property>
	</bean>
	<!--自定义的Roles Filter-->
	<bean id="anyRoles" class="com.ssm.utils.shiro.RolesAuthorizationFilter" />
	<!--以下两个是关于启用注解的配置 -->  
	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
	      depends-on="lifecycleBeanPostProcessor">
	      </bean>  
	<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
	    <property name="securityManager" ref="securityManager"/>  
	</bean>  
   
	<!-- 配置缓存管理器 -->
	<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
		<!-- 指定 ehcache 的配置文件 -->
		<!-- <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" /> -->
		<property name="cacheManager" ref="ehCacheManager"/>  
	</bean>
	<bean id="ehCacheManager" class ="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  
    <property name="configLocation" value="classpath:ehcache-shiro.xml" />  
    <property name="shared" value="true"></property>  
	</bean> 
	<!-- 配置进行授权和认证的 Realm -->
	<bean id="myRealm" class="com.ssm.utils.shiro.ShiroDbRealm"
		depends-on="ManagersMapper">
		<property name="ManagersService" ref="managersService" />
	</bean>
	<bean id="managersService" class="com.ssm.service.impl.ManagersServiceImpl" />
	<!-- 配置 Shiro 的 SecurityManager Bean. -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="cacheManager" ref="cacheManager" />
		<property name="realm" ref="myRealm" />
		<property name="sessionMode" value="native" />
	</bean>
	<!-- 配置 Bean 后置处理器: 会自动的调用和 Spring 整合后各个组件的生命周期方法. -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
</beans>  

3:utils目录下新建子包shiro,分别新建RolesAuthorizationFilter.java  和 ShiroDbRealm.java

RolesAuthorizationFilter.java 代码如下:

public class RolesAuthorizationFilter extends AuthorizationFilter{  
	  
    @Override  
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)  
            throws Exception {  
        Subject subject = getSubject(request, response);   
        String[] rolesArray = (String[]) mappedValue;   
  
        if (rolesArray == null || rolesArray.length == 0) {   
            //no roles specified, so nothing to check - allow access.   
            return true;   
        }   
  
        for(int i=0;i<rolesArray.length;i++){    
            if(subject.hasRole(rolesArray[i])){    
                return true;    
            }    
        }    
        return false;    
    }  
  
}
ShiroDbRealm.java代码如下:

public class ShiroDbRealm extends AuthorizingRealm {  
    @Autowired  
    private ManagersServiceImpl managersService;  
    public static final String SESSION_MANAGER_KEY = "Manager";  
    Logger logger = Logger.getLogger(this.getClass());
    /** 
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法 
     */  
    @Override  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {  
    	Managers managers = (Managers) SecurityUtils.getSubject().getSession().getAttribute(ShiroDbRealm.SESSION_MANAGER_KEY);  
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  
        logger.debug("power:"+managers.getPower()+";role:"+getRole(managers.getPower()));
        info.addRole(getRole(managers.getPower()));  
        return info;  
    }  
  
    /** 
     * 认证回调函数,登录信息和用户验证信息验证 
     */  
    @Override  
    protected AuthenticationInfo doGetAuthenticationInfo(  
            AuthenticationToken authcToken) throws AuthenticationException {  
        // 把token转换成User对象  
    	Managers managersLogin = tokenToManagers((UsernamePasswordToken) authcToken);  
        // 验证用户是否可以登录  
    	logger.debug("name:"+managersLogin.getId()+";pwd:"+managersLogin.getPassword());
//    	Managers ui = managersService.checkLogin(managersLogin);
    	Managers ui = managersService.login(managersLogin.getName(),managersLogin.getPassword());  
        if(ui == null)  
            return null; // 异常处理,找不到数据  
        // 设置session  
        Session session = SecurityUtils.getSubject().getSession();  
        session.setAttribute(ShiroDbRealm.SESSION_MANAGER_KEY, ui);   
        //当前 Realm 的 name  
        String realmName = this.getName();  
        //登陆的主要信息: 可以是一个实体类的对象, 但该实体类的对象一定是根据 token 的 username 查询得到的.  
//      Object principal = ui.getUsername();  
        Object principal = authcToken.getPrincipal();  
        return new SimpleAuthenticationInfo(principal, managersLogin.getPassword(), realmName);  
    }  
  
    private Managers tokenToManagers(UsernamePasswordToken authcToken) {  
    	Managers managers = new Managers(); 
    	managers.setName(authcToken.getUsername());  
    	managers.setPassword(String.valueOf(authcToken.getPassword()));  
        return managers;  
    }  
  
    //一定要写getset方法  
    public ManagersServiceImpl getManagersService() {  
        return managersService;  
    }  
  
    public void setManagersService(ManagersServiceImpl managersService) {  
        this.managersService = managersService;  
    }
    
    private String getRole(int power){
    	if(power == 1){
    		return "super_admin";
    	}else if (power == 2) {
    		return "admin";
		}else {
			return "users";
		}
    }
}
4:src下新建ehcache-shiro.xml

代码如下:

<?xml version="1.0" encoding="UTF-8"?>
 <ehcache updateCheck="false" name="Cache">  
    <defaultCache  
            maxElementsInMemory="10000"  
            eternal="false"  
            timeToIdleSeconds="120"  
            timeToLiveSeconds="120"  
            overflowToDisk="false"  
            diskPersistent="false"  
            diskExpiryThreadIntervalSeconds="120"  
            />  
</ehcache>

5:修改ManagersController,代码:

@Controller
public class ManagersController {

	static Logger logger = Logger.getLogger(ManagersController.class);
	
	@Autowired
	private ManagersService managersService;
	
	
	
	@RequestMapping(value = "do/managerLogin", produces = "text/html;charset=UTF-8;")
	@ResponseBody
	public String managerLogin(@RequestParam String name, @RequestParam String password,
			HttpSession httpSession, ModelMap map, HttpServletRequest request) {

		String code = "";
		String message = "";
		String data = null;
		logger.debug("name:"+name);
		logger.debug("password:"+password);
		
		Managers manager = managersService.login(name, password);
		if (manager == null) {
			code = "-1";
			message = "用户名或密码错误";
			return GiveBack.make(code, message, data);
		} else {
			//shiro-start
			UsernamePasswordToken token = 
					new UsernamePasswordToken(name,password);
	        Subject subject = SecurityUtils.getSubject();
			//shiro-end
	        try {
	            subject.login(token);
	        } catch (UnknownAccountException e) {
	        	code = "-1";
	        	message = e.toString();
	        	return GiveBack.make(code, message, data);
	        } catch (IncorrectCredentialsException e){
	        	code = "-1";
	        	message = e.toString();
	        	return GiveBack.make(code, message, data);
	        }
			JSONObject json = new JSONObject();
			int id = manager.getId();
			int power = manager.getPower();
			Date alertTime = manager.getAlterTime();
			if(alertTime != null){
				Timestamp now = new Timestamp(System.currentTimeMillis());
				json.put("power", power);
				json.put("name", name);
				json.put("id", id);
				if ((now.getTime() - alertTime.getTime()) / 1000 > 90 * 24 * 3600) {
					json.put("update", 1);
				} else {
					json.put("update", 0);
				}
			}else{
				json.put("update", 1);
			}
			
			code = "0";
			message = "";
			data = json.toString();
			return GiveBack.make(code, message, data);
		}
		
	}
	@RequestMapping(value = "/logout",method = RequestMethod.GET)
	public void logout(HttpServletRequest request,HttpServletResponse response) throws IOException{  
	    Subject subject = SecurityUtils.getSubject();  
	    if (subject != null) {  
	        try{  
	        	System.out.println("subject:"+subject);
	            subject.logout();  
	        }catch(Exception ex){
	        	
	        }  
	    } 
	    response.sendRedirect("./");  
	}
	
}
class GiveBack {

	
	public static String make(String code,String message,String data){
		JSONObject json = new JSONObject();
		json.put("code", code);
		json.put("message", message);
		json.put("data", data);
		return json.toString();
	}
}



大概看看,这是我从以前代码复制过来,有的都用不到;
6:SkipController代码:

@Controller
public class SkipController {


	@RequestMapping("admin/1")
	@ResponseBody
	public String a1(){
		return "admin/1";
	}
	@RequestMapping("admin/super/1")
	@ResponseBody
	public String a2(){
		return "admin/super/1";
	}
	@RequestMapping("users/1")
	@ResponseBody
	public String a3(){
		return "users/1";
	}
	@RequestMapping("/")
	public String backLogin() {
		return "login.html";
	}
	@RequestMapping("unauthorized")
	public String unauthorized() {
		return "unauthorized.html";
	}
	
	/*@RequestMapping("admin/management")
	public String a4(){
		return "management.html";
	}@RequestMapping("admin/super/management")
	public String a5(){
		return "management.html";
	}@RequestMapping("users/management")
	public String a6(){
		return "management.html";
	}*/
	

	
	
}



测试用的;

7:webroot下新建js目录,放入jquery-2.1.1.js;

8:web-inf 新建jsp目录,新建login.html  和 unauthorized.html

login.html  代码:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>欢迎登陆 </title>
  <script src="js/jquery-2.1.1.js" type="text/javascript"></script>
  <script type="text/javascript">
  $("#add").click(function(){
	  
  });
  function login(){
		var name = document.getElementById("name").value;
		var password = document.getElementById("password").value;
		
		
		$.ajax({
			url:"do/managerLogin",
			type:"POST",
			data:{
				name:name,
				password:password,
			},
			success:function(data) {
				var json = $.parseJSON(data);
				if(json.code == 0){
					location.href = "admin/1";
				}else{
					alert(json.message);
				}
			},
			error:function(e) {
				alert(e);
			}
		}); 

	}
  
</script>
</head>
<body>
<div class="header">
  <hr />
</div>
<div >
  <div >
    <h3>登录</h3>
    <hr>
    <br>

    <form method="post" οnsubmit="return false" action="##" class="am-form">
      <label for="name">账号:</label>
      <input type="text" name="" id="name" placeholder="账号" value="">
      <br>
      <label for="password">密码:</label>
      <input type="password" name="" id="password" placeholder="密码" value="">
      <br>
      
      <nobr>
      
      
      
      </nobr>
      <br>
      <br />
      <div class="am-cf">
        <input type="submit" name="" value="登 录"  οnclick="login()"
        >
        <input type="reset" name="" value="重 置"  
        >
      </div>
    </form>
    <hr>
    <p>© 2018 </p>
  </div>
</div>
</body>

</html>

unauthorized.html 代码:

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>欢迎登陆 </title>
  <script src="js/jquery-2.1.1.js" type="text/javascript"></script>
</head>
<body>
<div class="header">
  <hr />
</div>
<div >
  <div >
    <p>© 非法访问 </p>
  </div>
</div>
</body>

</html>

基本搞定;然后就是测试

admin  power为1的用户:



登录之后:



user  power为3的用户:


登录之后:

ok!

完整代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值