apache-shiro 学习笔记

阅读更多
(一) 看到SpringSide4居然也用shiro作为安全框架,不是用的spring-security。着实有点惊讶。
apache-shiro的强大可见一斑。

(二) apache-shiro依赖的包

	org.apache.shiro
	shiro-core
	1.2.1


	org.apache.shiro
	shiro-web
	1.2.1


	org.apache.shiro
	shiro-ehcache
	1.2.1


	org.apache.shiro
	shiro-spring
	1.2.1


除此之外还有一些东西也不可少spring, spring-mvc, ibatis等
  • spring.3.1.2
  • spring-mvc.3.1.2
  • ibatis.2.3.4
  • cglib.2.2


(三) demo采取比较典型的“User-Role-Permission”模型
-- -----------------------------------------------------
-- Table `shiro`.`TBL_PERMISSION`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `shiro`.`TBL_PERMISSION` ;

CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_PERMISSION` (
  `PERMISSION_ID` INT NOT NULL AUTO_INCREMENT ,
  `PERMISSION_NAME` VARCHAR(45) NULL ,
  PRIMARY KEY (`PERMISSION_ID`) ,
  UNIQUE INDEX `PERMISSION_NAME_UNIQUE` (`PERMISSION_NAME` ASC) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `shiro`.`TBL_ROLE`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `shiro`.`TBL_ROLE` ;

CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_ROLE` (
  `ROLE_ID` INT NOT NULL AUTO_INCREMENT ,
  `ROLE_NAME` VARCHAR(45) NULL ,
  PRIMARY KEY (`ROLE_ID`) ,
  UNIQUE INDEX `ROLE_NAME_UNIQUE` (`ROLE_NAME` ASC) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `shiro`.`TBL_USER`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `shiro`.`TBL_USER` ;

CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_USER` (
  `USER_ID` INT NOT NULL AUTO_INCREMENT ,
  `USER_USERNAME` VARCHAR(45) NOT NULL ,
  `USER_PASSWORD` CHAR(32) NOT NULL ,
  PRIMARY KEY (`USER_ID`) ,
  UNIQUE INDEX `USER_USERNAME_UNIQUE` (`USER_USERNAME` ASC) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `shiro`.`TBL_PERMISSION_ROLE`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `shiro`.`TBL_PERMISSION_ROLE` ;

CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_PERMISSION_ROLE` (
  `ROLE_ID` INT NOT NULL ,
  `PERMISSION_ID` INT NOT NULL ,
  PRIMARY KEY (`ROLE_ID`, `PERMISSION_ID`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `shiro`.`TBL_ROLE_USER`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `shiro`.`TBL_ROLE_USER` ;

CREATE  TABLE IF NOT EXISTS `shiro`.`TBL_ROLE_USER` (
  `ROLE_ID` INT NOT NULL ,
  `USER_ID` INT NOT NULL ,
  PRIMARY KEY (`ROLE_ID`, `USER_ID`) )
ENGINE = InnoDB;


自己实现一个UserDao, ibatis实现。
这个不是本文要记述的重点,简单贴一下代码。




	

	
		
		
		
		
	
	
	

	
		SELECT 
			u.USER_ID,
			u.USER_USERNAME,
			u.USER_PASSWORD,
			r.ROLE_ID,
			r.ROLE_NAME,
			p.PERMISSION_ID,
			p.PERMISSION_NAME
		FROM
		  tbl_user as u,
		  tbl_role as r,
		  tbl_permission as p,
		  tbl_permission_role as pr,
		  tbl_role_user as ru
		WHERE
		  u.USER_ID = ru.USER_ID
		AND
		  r.ROLE_ID = ru.ROLE_ID
		AND
		  p.PERMISSION_ID = pr.PERMISSION_ID
		AND
		  r.ROLE_ID = pr.ROLE_ID
	
	
	
	
	



public interface UserDao {

	User findUserByUsername(String username);

}

@Repository("userDao")
public class UserDaoImpl implements UserDao {

	@Resource
	private SqlMapClientTemplate sqlMapClientTemplate;
	
	@Override
	public User findUserByUsername(String username) {
		Validate.notEmpty(username, "用户名不可为null或empty string");
		return (User) sqlMapClientTemplate.queryForObject("user.select-01", username);
	}

}


(三) 用户和权限数据源是自己设计的,应该实现自己的Realm对象。
package com.ztgame.sd.security.realm;

import java.util.HashSet;
import java.util.Set;

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.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.ztgame.sd.dao.UserDao;
import com.ztgame.sd.domain.Permission;
import com.ztgame.sd.domain.Role;
import com.ztgame.sd.domain.User;

public class JdbcRealm extends AuthorizingRealm 
	implements
			Realm, 
			InitializingBean
{

	private UserDao userDao;

	// ------------------------------------------------------------------------------------------------------------

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(userDao);
	}

	// ------------------------------------------------------------------------------------------------------------

	@Override
	public String getName() {
		return getClass().getName();
	}

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		String username = (String) super.getAvailablePrincipal(principals);
		User user = userDao.findUserByUsername(username);
		
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		Set roles = new HashSet();
		Set permissions = new HashSet();

		for (Role role : user.getRoleSet()) {
			roles.add(role.getName());
			for (Permission per : role.getPermissionSet()) {
				permissions.add(per.getName());
			}
		}

		info.addRoles(roles);
		info.addStringPermissions(permissions);

		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {

		SimpleAuthenticationInfo info = null;

		UsernamePasswordToken upt = (UsernamePasswordToken) token;
		String username = upt.getUsername();
		User user = userDao.findUserByUsername(username);
		
		if (user == null) {
			throw new AuthenticationException();
		}

		info = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());

		return info;
	}

	// ------------------------------------------------------------------------------------------------------------

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

}


(四) apache-shiro的配置
web.xml


	
	
	
		shiroFilter
		org.springframework.web.filter.DelegatingFilterProxy
	
	
		shiroFilter
		/*
	

	




spring-shiro.xml


		
	

	
		
		
		
		
		
	

	
		
		
		
		
			
				
					
					
				
			
		
	

		

	
		
	

	

	

	
		
		
		
	



spring-mvc.xml



	

	
	

	
		
	




(五) jsp-taglib 支持
  • 登录之后
  • 不在登录状态时
  • 用户在没有RememberMe时
  • 用户在RememberMe时
  • 在有abc或者123角色时
  • 拥有角色abc
  • 没有角色abc
  • 拥有权限abc
  • 没有权限abc
  • 显示用户登录名

[官方文档] http://shiro.apache.org/web.html#Web-taglibrary

(六) 默认过滤器(10个)
  • anon -- org.apache.shiro.web.filter.authc.AnonymousFilter
  • authc -- org.apache.shiro.web.filter.authc.FormAuthenticationFilter
  • authcBasic -- org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter
  • perms -- org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter
  • port -- org.apache.shiro.web.filter.authz.PortFilter
  • rest -- org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter
  • roles -- org.apache.shiro.web.filter.authz.RolesAuthorizationFilter
  • ssl -- org.apache.shiro.web.filter.authz.SslFilter
  • user -- org.apache.shiro.web.filter.authc.UserFilter
  • logout -- org.apache.shiro.web.filter.authc.LogoutFilter


anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
roles:例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],每个参数通过才算通过,相当于hasAllRoles()方法。
perms:例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,其中method为post,get,delete等。
port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到schemal://serverName:8081?queryString,其中schmal是协议http或https等,serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
[官方文档] http://shiro.apache.org/web.html#Web-FilterChainDefinitions

(七) 常用元注释
  • @RequiresAuthentication 验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时
  • @RequiresUser 验证用户是否被记忆,user有两种含义:一种是成功登录的(subject.isAuthenticated()结果为true)另外一种是被记忆的(subject.isRemembered()结果为true)
  • @RequiresGuest 验证是否为匿名请求
  • @RequiresRoles 必须要有角色
  • @RequiresPermissions 必须要有权限

  • shiro-demo.zip (48.3 KB)
  • 下载次数: 654
  • shiro-db.zip (7.8 KB)
  • 下载次数: 378
  • shiro-db-dump.zip (880 Bytes)
  • 下载次数: 363

你可能感兴趣的:(spring-mvc,apache-shiro)