shiro-all包含shiro全部的包、shiro-core是核心包、shiro-web是與web整合、shiro-spring是與spring整合、shiro-ehcache是與EHCache整合、shiro-quartz是與任務調度quartz整合等等。java
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.2</version> </dependency>
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for u_permission -- ---------------------------- DROP TABLE IF EXISTS `u_permission`; CREATE TABLE `u_permission` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `url` varchar(256) DEFAULT NULL COMMENT 'url地址', `name` varchar(64) DEFAULT NULL COMMENT 'url描述', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of u_permission -- ---------------------------- INSERT INTO `u_permission` VALUES ('1', '/user/select', '用戶查詢'); INSERT INTO `u_permission` VALUES ('2', '/admin/add', '管理員添加'); INSERT INTO `u_permission` VALUES ('3', '/admin/delete', '管理員刪除'); -- ---------------------------- -- Table structure for u_role -- ---------------------------- DROP TABLE IF EXISTS `u_role`; CREATE TABLE `u_role` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL COMMENT '角色名稱', `type` varchar(10) DEFAULT NULL COMMENT '角色類型', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of u_role -- ---------------------------- INSERT INTO `u_role` VALUES ('1', 'admin', '1'); INSERT INTO `u_role` VALUES ('2', 'user', '1'); INSERT INTO `u_role` VALUES ('3', 'visitor', '1'); -- ---------------------------- -- Table structure for u_role_permission -- ---------------------------- DROP TABLE IF EXISTS `u_role_permission`; CREATE TABLE `u_role_permission` ( `rid` bigint(20) DEFAULT NULL COMMENT '角色ID', `pid` bigint(20) DEFAULT NULL COMMENT '權限ID' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of u_role_permission -- ---------------------------- INSERT INTO `u_role_permission` VALUES ('1', '3'); INSERT INTO `u_role_permission` VALUES ('1', '2'); INSERT INTO `u_role_permission` VALUES ('2', '1'); -- ---------------------------- -- Table structure for u_user -- ---------------------------- DROP TABLE IF EXISTS `u_user`; CREATE TABLE `u_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `nickname` varchar(20) DEFAULT NULL COMMENT '用戶暱稱', `email` varchar(128) DEFAULT NULL COMMENT '郵箱|登陸賬號', `pswd` varchar(32) DEFAULT NULL COMMENT '密碼', `create_time` datetime DEFAULT NULL COMMENT '建立時間', `last_login_time` datetime DEFAULT NULL COMMENT '最後登陸時間', `status` bigint(1) DEFAULT '1' COMMENT '1:有效,0:禁止登陸', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of u_user -- ---------------------------- INSERT INTO `u_user` VALUES ('1', 'admin', null, '123456', '2017-05-10 20:22:59', null, '1'); INSERT INTO `u_user` VALUES ('2', 'user', null, '123456', null, null, '1'); -- ---------------------------- -- Table structure for u_user_role -- ---------------------------- DROP TABLE IF EXISTS `u_user_role`; CREATE TABLE `u_user_role` ( `uid` bigint(20) DEFAULT NULL COMMENT '用戶ID', `rid` bigint(20) DEFAULT NULL COMMENT '角色ID' ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of u_user_role -- ---------------------------- INSERT INTO `u_user_role` VALUES ('1', '1'); INSERT INTO `u_user_role` VALUES ('2', '2'); SET FOREIGN_KEY_CHECKS=1;
@RestController public class AdminController { private static Logger logger = LoggerFactory.getLogger(AdminController.class); @Autowired private URoleDao uRoleDao; //跳轉到登陸表單頁面 @RequestMapping(value = "/login", method = RequestMethod.GET) public String login() { return "need login"; } //登陸成功後,跳轉的頁面 @RequestMapping("/success") public String index(Model model) { return "success"; } //未登陸,能夠訪問的頁面 @RequestMapping("/index") public String list(Model model) { return "index"; } //登錄驗證,這裏方便url測試,正式上線須要使用POST方式提交 @RequestMapping(value = "/ajaxLogin", method = RequestMethod.GET) public String index(UUser user) { if (user.getNickname() != null && user.getPswd() != null) { UsernamePasswordToken token = new UsernamePasswordToken(user.getNickname(), user.getPswd(), "login"); Subject currentUser = SecurityUtils.getSubject(); logger.info("對用戶[" + user.getNickname() + "]進行登陸驗證..驗證開始"); try { currentUser.login( token ); //驗證是否登陸成功 if (currentUser.isAuthenticated()) { logger.info("用戶[" + user.getNickname() + "]登陸認證經過(這裏能夠進行一些認證經過後的一些系統參數初始化操做)"); System.out.println("用戶[" + user.getNickname() + "]登陸認證經過(這裏能夠進行一些認證經過後的一些系統參數初始化操做)"); return "redirect:/"; } else { token.clear(); System.out.println("用戶[" + user.getNickname() + "]登陸認證失敗,從新登錄"); return "redirect:/login"; } } catch ( UnknownAccountException uae ) { logger.info("對用戶[" + user.getNickname() + "]進行登陸驗證..驗證失敗-username wasn't in the system"); } catch ( IncorrectCredentialsException ice ) { logger.info("對用戶[" + user.getNickname() + "]進行登陸驗證..驗證失敗-password didn't match"); } catch ( LockedAccountException lae ) { logger.info("對用戶[" + user.getNickname() + "]進行登陸驗證..驗證失敗-account is locked in the system"); } catch ( AuthenticationException ae ) { logger.error(ae.getMessage()); } } return "login"; } /** * ajax登陸請求接口方式登錄 * @param username * @param password * @return */ @RequestMapping(value="/ajaxLogin",method= RequestMethod.POST) @ResponseBody public Map<String,Object> submitLogin(@RequestParam(value = "nickname") String username, @RequestParam(value = "pswd") String password) { Map<String, Object> resultMap = new LinkedHashMap<String, Object>(); try { UsernamePasswordToken token = new UsernamePasswordToken(username, password); SecurityUtils.getSubject().login(token); resultMap.put("status", 200); resultMap.put("message", "登陸成功"); } catch (Exception e) { resultMap.put("status", 500); resultMap.put("message", e.getMessage()); } return resultMap; } //登出 @RequestMapping(value = "/logout") public String logout(){ return "logout"; } //錯誤頁面展現 @GetMapping("/403") public String error(){ return "error ok!"; } //管理員功能 @RequiresRoles("admin") @RequiresPermissions("管理員添加") @RequestMapping(value = "/admin/add") public String create(){ return "add success!"; } //用戶功能 @RequiresRoles("user") @RequiresPermissions("用戶查詢") @RequestMapping(value = "/user/select") public String detail(){ return "select success"; } }
shiroConfiguration.javaweb
@Configuration public class ShiroConfiguration { /** * ShiroFilterFactoryBean 處理攔截資源文件問題。 * 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的,覺得在 * 初始化ShiroFilterFactoryBean的時候須要注入:SecurityManager * * Filter Chain定義說明 一、一個URL能夠配置多個Filter,使用逗號分隔 二、當設置多個過濾器時,所有驗證經過,才視爲經過 * 三、部分過濾器可指定參數,如perms,roles * */ @Bean(name = "lifecycleBeanPostProcessor") public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean(name = "shiroRealm") @DependsOn("lifecycleBeanPostProcessor") public ShiroRealm shiroRealm() { ShiroRealm realm = new ShiroRealm(); return realm; } @Bean(name = "ehCacheManager") @DependsOn("lifecycleBeanPostProcessor") public EhCacheManager ehCacheManager(){ EhCacheManager ehCacheManager = new EhCacheManager(); return ehCacheManager; } @Bean(name = "securityManager") public DefaultWebSecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(shiroRealm()); securityManager.setCacheManager(ehCacheManager());//用戶受權/認證信息Cache, 採用EhCache 緩存 return securityManager; } @Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){ ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); // 過濾鏈定義,從上向下順序執行,通常將 /**放在最爲下邊 Map<String, String> filterChainDefinitionManager = new LinkedHashMap<String, String>(); // 配置退出過濾器,其中的具體的退出代碼Shiro已經替咱們實現了 filterChainDefinitionManager.put("/logout", "logout"); // authc:全部url都必須認證經過才能夠訪問; anon:全部url都均可以匿名訪問 filterChainDefinitionManager.put("/user/**", "authc,roles[user]"); filterChainDefinitionManager.put("/admin/**", "authc,roles[admin]"); filterChainDefinitionManager.put("/login", "anon"); filterChainDefinitionManager.put("/index", "anon"); filterChainDefinitionManager.put("/ajaxLogin", "anon"); filterChainDefinitionManager.put("/statistic/**", "anon"); filterChainDefinitionManager.put("/**", "authc,roles[user]");//其餘資源所有攔截 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionManager); // 若是不設置默認會自動尋找Web工程根目錄下的"/login.jsp"頁面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登陸成功後要跳轉的連接 shiroFilterFactoryBean.setSuccessUrl("/success"); // 未受權界面 shiroFilterFactoryBean.setUnauthorizedUrl("/403"); return shiroFilterFactoryBean; } @Bean @ConditionalOnMissingBean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator(); daap.setProxyTargetClass(true); return daap; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor aasa = new AuthorizationAttributeSourceAdvisor(); aasa.setSecurityManager(securityManager); return aasa; } }
shiroRealm.javaajax
public class ShiroRealm extends AuthorizingRealm { private Logger logger = LoggerFactory.getLogger(ShiroRealm.class); //通常這裏都寫的是servic,這裏省略直接調用dao @Autowired private UUserDao uUserDao; @Autowired private URoleDao uRoleDao; @Autowired private UPermissionDao uPermissionDao; /** * 登陸認證 * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; logger.info("驗證當前Subject時獲取到token爲:" + token.toString()); //查出是否有此用戶 String username = token.getUsername(); UUser hasUser = uUserDao.selectAllByName(username); if (hasUser != null) { // 若存在,將此用戶存放到登陸認證info中,無需本身作密碼對比,Shiro會爲咱們進行密碼對比校驗 List<URole> rlist = uRoleDao.findRoleByUid(hasUser.getId());//獲取用戶角色 List<UPermission> plist = uPermissionDao.findPermissionByUid(hasUser.getId());//獲取用戶權限 List<String> roleStrlist=new ArrayList<String>();用戶的角色集合 List<String> perminsStrlist=new ArrayList<String>();//用戶的權限集合 for (URole role : rlist) { roleStrlist.add(role.getName()); } for (UPermission uPermission : plist) { perminsStrlist.add(uPermission.getName()); } hasUser.setRoleStrlist(roleStrlist); hasUser.setPerminsStrlist(perminsStrlist); // 若存在,將此用戶存放到登陸認證info中,無需本身作密碼對比,Shiro會爲咱們進行密碼對比校驗 return new SimpleAuthenticationInfo(hasUser, hasUser.getPswd(), getName()); } return null; } /** * 權限認證 * @param principalCollection * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { logger.info("##################執行Shiro權限認證##################"); UUser user = (UUser) principalCollection.getPrimaryPrincipal(); if (user != null) { //權限信息對象info,用來存放查出的用戶的全部的角色(role)及權限(permission) SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //用戶的角色集合 info.addRoles(user.getRoleStrlist()); //用戶的權限集合 info.addStringPermissions(user.getPerminsStrlist()); return info; } // 返回null的話,就會致使任何用戶訪問被攔截的請求時,都會自動跳轉到unauthorizedUrl指定的地址 return null; } }