1. 程式人生 > >shiro整合spring mvc的應用

shiro整合spring mvc的應用

1.首先準備五張表,分別為 使用者表、角色表、許可權表、使用者角色表、角色許可權表

      

CREATE TABLE `sys_users` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) DEFAULT NULL,
  `password` varchar(100) DEFAULT NULL,
  `salt` varchar(100) DEFAULT NULL,
  `locked` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_sys_users_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


CREATE TABLE `sys_roles` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(100) DEFAULT NULL,
  `description` varchar(100) DEFAULT NULL,
  `available` tinyint(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_sys_roles_role` (`role_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;



CREATE TABLE `sys_permissions` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `permission` varchar(100) DEFAULT NULL,
  `perm_url` varchar(100) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `description` varchar(100) DEFAULT NULL,
  `available` tinyint(1) DEFAULT '0',
  `type` int(1) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_sys_permissions_permission` (`permission`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `sys_users_roles` (
  `user_id` bigint(20) NOT NULL DEFAULT '0',
  `role_id` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



CREATE TABLE `sys_roles_permissions` (
  `id` int(11) NOT NULL,
  `role_id` bigint(20) NOT NULL DEFAULT '0',
  `permission_id` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`role_id`,`permission_id`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;













2.我做的這個專案不是maven專案,所以我需要匯入引入shiro的jar包,,如果你的專案是maven專案的話,可以引入maven依賴

	<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
			<version>1.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-ehcache</artifactId>
			<version>1.2.2</version>
		</dependency>

3.分別建立使用者、角色以及許可權的實體

4、在web.xml新增過濾器,攔截所有的url請求

  <!-- spring 提供的用於整合shiro的過濾器 -->
  <filter>
  	<filter-name>shiroFilter</filter-name>
  	<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
  <filter-mapping>
  	<filter-name>shiroFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

5、定義和注入securityManager

<!-- 配置一個和web.xml中DelegatingFilterProxy同名的bean物件 ,當前物件(工廠)用於建立shiro框架提供的多個過濾器的-->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 注入安全管理器物件 -->
		<property name="securityManager" ref="securityManager"></property>
		<!-- 注入登入的訪問URL -->
		<property name="loginUrl" value="/login"></property>
		<!-- 登入成功後的跳轉頁面 -->
		<property name="successUrl" value="/index"></property>
		<!-- 注入許可權不足提示頁面 -->
		<property name="unauthorizedUrl" value="/unauthorizedUrl"></property>
		<!-- URL攔截規則
		1). anon 可以被匿名訪問
     	2). authc 必須認證(即登入)後才可能訪問的頁面
     	3).perms['']表示需要某個許可權
     	-->
		<property name="filterChainDefinitions">
			<value>
				/css/** = anon
				/js/** = anon
				/images/** = anon
				/validatecode.jsp* = anon
				/login =anon
				/login* = anon
				/page_base_staff.action = perms["staff.query"]
				/* = authc
			</value>
		</property>
	</bean>
	
	<!-- 註冊一個安全管理器物件 -->
	<bean id="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realms" ref="shiroDbRealm"></property>
	</bean>

    <!-- 註冊自定義realm -->
	<bean id="shiroDbRealm" class="cn.my.blog.shiro.ShiroDbRealm"></bean>
6、自定義Realm內容
public class ShiroDbRealm extends AuthorizingRealm{
	
	@Autowired
	private UserService userService;

	/**
	 * 授權
	 * @param principals
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		  User user = (User) principals.getPrimaryPrincipal();
		  
		  List<Role> roleList = userService.findRolesByUserId(user.getId());
		  SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		  for(Role role : roleList){
			  info.addRole(role.getRoleName());
			  info.addStringPermissions(role.getPermList());
		  }
		  return info;
	}

	/**
	 * 認證
 	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token ;
		String username = upToken.getUsername();
		User user = userService.findUserByUsername(username);
		if(username == null){
			return null;
		}else{
			String dbPassword = user.getPassword();
			AuthenticationInfo info = new SimpleAuthenticationInfo(user, dbPassword,this.getClass().getSimpleName());
			return info;
		}
	}
}

7、使用shiro進行登入

	@RequestMapping(method = RequestMethod.POST)
	public String loginPost(HttpServletRequest req,Model model){
		String message = "登入成功";
		//獲取subject
		Subject subject = SecurityUtils.getSubject();
		String password = req.getParameter("password");
		password = MD5Utils.md5(password);
		AuthenticationToken token = new UsernamePasswordToken(req.getParameter("username"), password);
		try{
			//使用shiro進行登入,報錯及驗證不通過
			subject.login(token);
			User user = (User)subject.getPrincipal();
			session.setAttribute("user", user);
		}catch(UnknownAccountException e){
			e.printStackTrace();
			message="使用者名稱或密碼錯誤";
			model.addAttribute("message",message);
			return LOGIN;
		}catch (Exception e) {
			e.printStackTrace();
			message="登入失敗";
			model.addAttribute("message",message);
			return LOGIN;
		}
		 model.addAttribute("message",message);
		 return MAIN_INDEX;
	}