`
__SuRa丶Rain
  • 浏览: 45105 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

基于Shiro 拦截URL,实现权限控制

阅读更多

虽然网上很多关于Shiro的样例,但是LZ看了很多,觉得他们好多都不是自己想要的。

 

不是没有URL过滤功能,就是写死在xml配置文件里,还有好多不能使。

 

LZ不才,只能写一些简单样例给大家看看。

 

基础要求:SSH都会,了解权限管理的架构。

 

接下来是代码:

 

 先给出表

CREATE TABLE `t_privilege` (
  `id` int(11) NOT NULL auto_increment,
  `perms` varchar(255) default NULL,
  `url` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


CREATE TABLE `t_user` (
  `id` int(11) NOT NULL auto_increment,
  `password` varchar(255) default NULL,
  `username` varchar(255) default NULL,
  `role_id` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `FKCB63CCB613F1722F` (`role_id`),
  CONSTRAINT `FKCB63CCB613F1722F` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;


CREATE TABLE `t_role` (
  `id` int(11) NOT NULL,
  `name` varchar(255) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `t_role_t_privilege` (
  `t_role_id` int(11) NOT NULL,
  `privileges_id` int(11) NOT NULL,
  PRIMARY KEY  (`t_role_id`,`privileges_id`),
  KEY `FK6947A6C85C5EE234` (`privileges_id`),
  KEY `FK6947A6C8CF836564` (`t_role_id`),
  CONSTRAINT `FK6947A6C8CF836564` FOREIGN KEY (`t_role_id`) REFERENCES `t_role` (`id`),
  CONSTRAINT `FK6947A6C85C5EE234` FOREIGN KEY (`privileges_id`) REFERENCES `t_privilege` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 这里设计的就是一个User,一个Role。但是Role有很多的URL。

 

DAO,Service 就不给了。

 

action:

 

 

package com.vti.action;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import com.vti.model.User;
import com.vti.service.UserService;

@Controller
@RequestMapping(value="/")
public class LoginController {
	
	private UserService userService;
	
	public UserService getUserService() {
		return userService;
	}

	@Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	@RequestMapping(value = "/login")
	public String login(String username, String password, ModelMap map){
		if(this.userService.checkUser(username, password)){
			setLogin(username, password);
			return "index.do";
		}else{
			map.addAttribute("msg", "username or password error !");
			return "login.jsp";
		}
	}
	
	@RequestMapping(value = "/index")
	public String index(HttpServletRequest request, HttpServletResponse response,ModelMap map){
		Subject currentUser = SecurityUtils.getSubject();
		User user=userService.getByUserLoginId(currentUser.getPrincipal().toString());
		map.addAttribute("LoginUser",user);
		return "index.jsp";
	}
	
	@RequestMapping(value = "/logout")
	public String logout(HttpServletRequest request, HttpServletResponse response,ModelMap map){
		Subject currentUser = SecurityUtils.getSubject();
		currentUser.logout();
		return "login.jsp";
	}
	
	private void setLogin(String userName, String password) {
		Subject currentUser = SecurityUtils.getSubject();
		if (!currentUser.isAuthenticated()) {
			UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
			token.setRememberMe(false);
			currentUser.login(token);
		}
	}
}

 

 

 

web.xml

 

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<welcome-file-list>
		<welcome-file>login.jsp</welcome-file>
	</welcome-file-list>


	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:beans.xml</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<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>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
		<dispatcher>ERROR</dispatcher>
	</filter-mapping>

	<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:SpringMVC.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springMVC</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	
</web-app>

 

 

 

beans.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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

	<context:annotation-config />
	<context:component-scan base-package="com.vti"></context:component-scan>
	
	<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost:3306/test" />
		<property name="username" value="root" />
		<property name="password" value="admin" />
		
		<property name="initialSize" value="5" />
		<property name="maxActive" value="500" />
		<property name="maxIdle" value="50" />
		<property name="minIdle" value="10" />
		<property name="timeBetweenEvictionRunsMillis" value="3600000" />
		<property name="minEvictableIdleTimeMillis" value="3600000" />
	
	</bean>
	
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="packagesToScan">
			<list>
				<value>com.vti.model</value>
				</list>
		</property>
		
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				</props>
		</property>
		
	</bean>

	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	
	<bean id="txManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<aop:config>
		<aop:pointcut id="bussinessService" expression="execution(public * com.vti.service.*.*(..))" />
		<aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" />
	</aop:config>

	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="find*" read-only="true"/>
			<tx:method name="get*" read-only="true"/>
		</tx:attributes>
	</tx:advice>
	
	
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="shiroDbRealm" />
	</bean>
	
	<bean id="shiroDbRealm" class="com.vti.shiro.MyShiroRealm" />
	
	<bean id="chainDefinitionSectionMetaSource" class="com.vti.shiro.ChainDefinitionSectionMetaSource">
    	<property name="filterChainDefinitions">
       		<value>
       			/login.do = anon
       			/logout.do = logout
        	</value>
    	</property>
	</bean>
	
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<property name="securityManager" ref="securityManager" />
		<property name="loginUrl" value="/login.jsp" />
		<property name="successUrl" value="/index.do" />
		<property name="unauthorizedUrl" value="/403.htm" />
		
		<property name="filterChainDefinitionMap" ref="chainDefinitionSectionMetaSource" />
	</bean>
	
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
	
	<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>
	
</beans>

 

 

 

 

 

ChainDefinitionSectionMetaSource

 

 

package com.vti.shiro;

import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.apache.shiro.config.Ini;
import org.apache.shiro.config.Ini.Section;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.util.StringUtils;

import com.vti.dao.PrivilegeDao;
import com.vti.model.Privilege;

public class ChainDefinitionSectionMetaSource implements FactoryBean<Ini.Section>{
	
	public static final String PREMISSION_STRING="perms[\"{0}\"]";
	
	private String filterChainDefinitions;
	
	private PrivilegeDao privilegeDao;

    public PrivilegeDao getPrivilegeDao() {
		return privilegeDao;
	}
    
    public String getFilterChainDefinitions() {
		return filterChainDefinitions;
	}
    
    @Resource
	public void setFilterChainDefinitions(String filterChainDefinitions) {
    	String fiter="";//改正后的url配置
    	List<Privilege> list = privilegeDao.getAll();
        for (Iterator<Privilege> it = list.iterator(); it.hasNext();) {
        	Privilege privilege = it.next();
            if(!StringUtils.isEmpty(privilege.getUrl())) {
            	fiter+="/"+privilege.getUrl()+" = authc," +MessageFormat.format(PREMISSION_STRING,privilege.getPerms()) +"\n";
            }//追加beans.xml中已经有的过滤
        }
        System.out.println(filterChainDefinitions+fiter);
		this.filterChainDefinitions = filterChainDefinitions+fiter;
	}

	@Resource
	public void setPrivilegeDao(PrivilegeDao privilegeDao) {
		this.privilegeDao = privilegeDao;
	}
	
    public Section getObject(){
        Ini ini = new Ini();//网上好多都是在这里配置URL的。但是发现是错误的。
        ini.load(filterChainDefinitions);
        Ini.Section section = ini.getSection(Ini.DEFAULT_SECTION_NAME);
        return section;
    }

    public Class<?> getObjectType() {
        return this.getClass();
    }

    public boolean isSingleton() {
        return false;
    }

}

 

 

 

 

MyShiroRealm

 

 

package com.vti.shiro;

import java.util.List;

import javax.annotation.Resource;

import org.apache.shiro.authc.AccountException;
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.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
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.util.StringUtils;

import com.vti.model.Privilege;
import com.vti.model.User;
import com.vti.service.UserService;

public class MyShiroRealm extends AuthorizingRealm{
	private UserService userService;
	
	public UserService getUserService() {
		return userService;
	}
	
	@Resource
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		if(principals == null){
			throw new AuthorizationException("principals should not be null");
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		String username =(String) principals.fromRealm(this.getName()).iterator().next();
		List<Privilege> privileges = userService.getAllPrivilegeByUserId(username);
		for(Privilege p : privileges){
			info.addStringPermission(p.getPerms());
		}
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authecToken){
		UsernamePasswordToken token = (UsernamePasswordToken)authecToken;
		
		if(StringUtils.isEmpty(token.getUsername())){
			throw new AccountException("用户名不能为空");
		} 
		
		User user = userService.getByUserLoginId(token.getUsername());
		if(user == null){
			throw new UnknownAccountException("用户名没找到");
		} else if(user.getPassword().equals(new String(token.getPassword()))){
			return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), this.getName());
		} else {
			throw new AuthenticationException("授权失败");
		}
	}
	
	
}

 

 

 

给出index,jsp

有shiro的标签使用

<%@ page language="java" contentType="text/html; utf-8" pageEncoding="utf-8"%>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>

<!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; utf-8">
		<title>Insert title here</title>
	</head>
	<body>
	
	<shiro:authenticated>
		<h3>Login User Can see it</h3>
		<h4>You are  ${LoginUser.role.name}, Your name is ${LoginUser.username}</h4>
	</shiro:authenticated>
	
	<shiro:hasPermission name="set">
		<a href="3.jsp">系统设置</a><br>
	</shiro:hasPermission>
	<shiro:hasPermission name="view">
		<a href="2.jsp">总账查看</a><br>
	</shiro:hasPermission>
	<shiro:hasPermission name="sale">
		<a href="1.jsp">卖货</a><br><br>
	</shiro:hasPermission>
	
	<shiro:notAuthenticated>
		Please <a href="login.jsp">login</a> in order to update your credit card information.
	</shiro:notAuthenticated>
	
	<shiro:authenticated>
		<a href="logout.do">注销</a>
	</shiro:authenticated>
	
	</body>
	
</html>

 

 

最后讲下逻辑思路:

 

 系统分为三个等级。 分别是:售货员,经理,管理员

 售货员:登录,卖货,注销

经理:查账,登录,卖货,注销

管理员:系统设置,查账,登录,卖货,注销。

 

主要是围绕这样的功能去分配url的。

 

数据库在附件中给出。

 

  • 大小: 16 KB
分享到:
评论
1 楼 liuyachao111 2018-04-09  
写的太棒了,这个动态控制url的好使

相关推荐

    SpringBoot 集成 Shiro 实现动态uri权限

    SpringBoot集成Shiro实现动态URI权限是一个常见的权限管理实践,主要目的是为了实现更灵活、更安全的用户访问控制。在Web应用中,权限控制通常包括角色管理、菜单管理、操作权限(URI)管理等,而动态URI权限则允许...

    spring boot整合shiro实现url请求过滤

    本demo为Spring boot整合shiro,以mybatis plus做dao层交互数据,实现了读取数据库用户数据实现用户登录,权限认证,读取数据库中用户对应的url请求,实现请求的过滤。自定义了relam和过滤器来实现这些功能

    SpringBoot+Shiro+JWT+Jedis+MybatisPlus+前后端分离+基于url通用权限管理系统

    总的来说,这个系统通过SpringBoot构建基础框架,利用Shiro进行权限控制,结合JWT实现无状态认证,借助Jedis提升性能,运用MybatisPlus简化数据库操作,实现了基于URL的权限管理。这种设计不仅提高了系统的安全性,...

    SSM+Shiro实现权限角色控制

    之后,Shiro通过对请求URL的拦截,根据用户的权限信息决定是否允许访问特定资源。 Eclipse作为一个集成开发环境(IDE),在这里被用来编写、调试和运行项目。开发者可以在Eclipse中导入此项目,配置好Maven、Tomcat...

    SpringBoot与Shiro整合-权限管理实战源码.zip

    - **过滤器链配置**:定义Shiro的过滤器链,如anon(匿名访问)、authc(基本认证)、perms(权限控制)等,指定哪些URL需要经过哪些过滤器处理。 - **启动Shiro**:在SpringBoot的主配置类中,通过`@EnableWebMvc...

    springboot+shiro+layuimini实现后台管理系统的权限控制

    2. **授权**:Shiro支持基于角色的访问控制(RBAC),可以灵活地定义用户角色及权限,如URL拦截、方法级别的权限控制等。 3. **会话管理**:Shiro可以统一管理会话,包括会话超时、分布式会话等,提高系统的安全性。...

    基于shiro、springmvc、mybatis权限管理系统

    5. **权限管理**:Shiro进行用户认证和授权,通过拦截器或者Filter实现权限控制。 **关键模块** 1. **用户管理**:包括用户的注册、登录、密码修改等功能。 2. **角色管理**:创建、分配角色,角色可以拥有特定的...

    shiro登录拦截校验demo

    - **Filters**:Shiro通过Filter链进行请求拦截,实现权限控制。 3. **Shiro的配置**: - **shiro.ini或Java配置**:定义Subject的行为,包括Realm配置、安全约束等。 - **Web.xml配置**:设置Shiro Filter链,...

    spring boot+shiro+mybatis实现不同用户登录显示不同的权限菜单

    3. **权限细粒度控制**:不仅可以基于角色分配权限,还可以对单个URL或者资源进行权限控制,实现更灵活的权限策略。 总的来说,这个项目展示了如何利用Spring Boot、Shiro和MyBatis的集成,实现一个功能完善的权限...

    springboot shiro基于redis分布式权限实现完整案例代码

    5. **安全拦截**:配置Shiro Filter Chain,定义哪些URL需要进行权限控制。 6. **启动与集成**:在Spring Boot的主类中,通过`@EnableShiroWeb`注解启用Shiro,或者自定义WebSecurityManager并注册为Bean。 接下来...

    shiro权限案例demo

    Apache Shiro是一个强大且易用的Java安全框架,主要用于身份认证、授权(权限控制)、会话管理和加密等安全相关的功能。在这个"shiro权限案例demo"中,我们将深入探讨Shiro如何实现用户权限的管理。 首先,让我们...

    权限管理系统,基于 shiro,spring mvc,mybatis 框架开发

    总结来说,这个基于Shiro、Spring MVC和MyBatis的权限管理系统实现了从用户认证到资源访问控制的全过程,为企业级应用提供了安全的访问控制机制。通过学习和实践这个项目,开发者可以深入理解Java Web安全框架的应用...

    shiro权限框架

    - **URL拦截**:利用Shiro内置的过滤器来拦截URL,实现权限控制。 - **方法注解**:通过在业务逻辑的方法上添加注解来控制权限。 - **页面标签**:提供了一组标签库,用于根据权限动态展示或隐藏页面元素。 ...

    Spring整合Shiro做权限控制模块详细案例分析

    在本文中,我们将深入探讨如何将Spring框架与Apache Shiro安全框架整合,以实现一个强大的权限控制模块。Spring是企业级应用开发的事实标准,而Shiro则是一个轻量级的安全框架,提供了身份验证、授权、会话管理和...

    jfinal整合shiro权限控制(从数据库读取配置信息)

    通过这个工厂,我们可以根据JFinal的路由或URL来动态配置Shiro的过滤器,实现对不同URL的权限控制。 2. **JfinalShiroFilter.java**:这是JFinal与Shiro整合的一个自定义过滤器。该过滤器可能负责拦截请求,执行...

    Apache shiro权限控制基础配置代码

    在实际项目中,你可以结合Spring Boot、Spring MVC等框架,通过注解或拦截器实现权限控制。例如,使用`@RequiresPermissions`或`@RequiresRoles`注解限制访问特定方法。 总结,Apache Shiro是一个强大且易用的安全...

    shiro整合SpringBoot

    Shiro 提供了 `@RequiresAuthentication`、`@RequiresPermissions` 和 `@RequiresRoles` 等注解,可以直接在控制器方法上使用,实现基于注解的权限控制。 4. **模板(templates)案例**: - 如果项目使用了模板...

    ShiroDemo权限管理例子

    5. **Web集成**:Shiro可以直接与Web应用结合,提供过滤器实现基于URL的安全控制,如`shiroFilter`,它可以根据配置拦截用户请求并进行相应的权限检查。 6. **测试**:Shiro提供了一些测试工具,方便开发者在单元...

    java的实现权限控制shiro jwt.docx

    为了实现权限控制,我们需要定义Shiro的配置,包括 Realm(域)来处理用户认证和授权。在`UserRealm`类中,我们可以实现`doGetAuthenticationInfo`和`doGetAuthorizationInfo`方法,分别用于获取用户的认证信息和...

Global site tag (gtag.js) - Google Analytics