手把手带你掌握JavaShiro安全框架,看完即用
Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
Shrio的主要功能:Authentication:用户认证(登录)Authorization:权限控制Session Management:会话管理Cryptography:数据加密Web Support:支持web的APICaching:缓存Concurrency:支持多线程应用程序Testing:测试的支持"Run As":假设一个用户为另一个用户的身份"Remember Me":在Session中保存用户身份基本原理Shiro的基本架构:
Shiro有三个核心的概念:Subject、SecurityManager和Realms。Subject:Subject实质上是一个当前执行用户的特定的安全"视图",开发者所写的应用代码就通过Subject与Shiro框架进行交互。所有Subject实例都必须绑定到一个SecurityManager上,当使用一个Subject实例时,Subject实例会和SecurityManager进行交互,完成相应操作。SecurityManager:SecurityManager是Shiro的核心部分,作为一种"保护伞"对象来协调内部安全组件共同构成一个对象图。开发人员并不直接操作SecurityManager,而是通过Subject来操作SecurityManager来完成各种安全相关操作。Realms:Realms担当Shiro和应用程序的安全数据之间的"桥梁"或"连接器"。从本质来讲,Realm是一个特定安全的DAO,Realm中封装了数据操作的模块和用户自定义的认证匹配过程。SecurityManager可能配置多个Realms,但至少要有一个。使用方法
注:该示例基于一个Maven管理的SSH项目
1. 在Maven中添加Shiro依赖 org.apache.shiro shiro-all 1.2.3
注:Shiro官方现在不推荐这种用法,因为可能会导致Maven运行错误
2. 在web.xml添加核心过滤器,且必须放在Struts2核心过滤器前面 shiroFilter org.springframework.web.filter.DelegatingFilterProxy targetFilterLifecycle true shiroFilter /*
3.在Spring配置文件中添加如下代码,且放在事务管理器之前
4. 在Spring配置文件中配置Shiro,建议单独出一个applicationContext-shiro.xml进行配置(编写完成后记得在总的配置文件中引入该配置文件)applicationContext-shiro.xml <?xml version="1.0" encoding="UTF-8"?> /index.jsp* = anon /home* = anon /sysadmin/login/login.jsp* = anon /sysadmin/login/logout.jsp* = anon /login* = anon /logout* = anon /components/** = anon /css/** = anon /images/** = anon /js/** = anon /make/** = anon /skin/** = anon /stat/** = anon /ufiles/** = anon /validator/** = anon /resource/** = anon /** = authc /*.* = authc
在这里配置了核心的SecurityManager,SecurityManager中注入了realm和cacheManager,因此需要配置realm和cacheManager,Realm是自定义的,其中注入了userService,用来进行查询数据库数据的相关操作,还注入了credentialsMatcher属性,这个是开发者自定义的比较器。配置CacheManager时,使用了ehcache,在最后也进行了配置,并且编写了ehcache的配置文件,这些操作在下述步骤进行。
在shiroFilter的配置中配置了要过滤的目录,其中一个*号表示匹配当前目录后的参数,两个*号表示匹配该目录及其子目录及参数。等号后面是Shiro各类过滤器的简称,anon表示匿名过滤器,表示可以匿名访问这些资源,authc表示需要验证用户身份才能访问,还有8种过滤器,在此就不再详述了。
5. Ehcache的配置文件ehcache-shiro.xml <?xml version="1.0" encoding="UTF-8"?>
6. 编写自定义的credentialsMatcherDemoCredentialsMatcher.java public class DemoCredentialsMatcher extends SimpleCredentialsMatcher { /** * 密码比较的规则 * token:用户在界面输入的用户名和密码 * info: 从数据库中得到的加密数据 */ @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { // 获取用户输入的密码,并加密 UsernamePasswordToken upToken = (UsernamePasswordToken) token; String md5Pwd = Encrypt.md5(new String(upToken.getPassword()), upToken.getUsername()); // 获取数据库中的加密密码 String pwd = (String) info.getCredentials(); // 返回比较结果 return this.equals(md5Pwd, pwd); } } Encrypt是一个进行MD5加密的工具类 Encrypt.java public class Encrypt { public static String md5(String password, String salt) { return new Md5Hash(password, salt, 2).toString(); } }
7. 编写自定义的realmAuthRealm.java public class AuthRealm extends AuthorizingRealm { private IUserService userService; public void setUserService(IUserService userService) { this.userService = userService; } /** * 授权,当jsp页面遇到shiro标签会执行该方法 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) { System.out.println("授权"); User user = (User) pc.fromRealm(this.getName()).iterator().next(); // 根据realm名字找到对应的realm List permissions = new ArrayList(); Set roles = user.getRoles(); for (Role role : roles) { Set modules = role.getModules(); for (Module module : modules) { permissions.add(module.getName()); } } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permissions); // 添加用户的权限 return info; } /** * 认证 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("认证"); UsernamePasswordToken upToken = (UsernamePasswordToken) token; List list = userService.find("from User u where u.userName = ?", User.class, new String[]{upToken.getUsername()}); if (list != null && list.size() > 0) { User user = list.get(0); AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName()); return info; } return null; // 返回null抛出异常 } }
8. 登录操作try { // 1、得到Subject Subject subject = SecurityUtils.getSubject(); // 2、调用登录方法---AuthRealm#doGetAuthenticationInfo() subject.login(new UsernamePasswordToken(username, password)); // 3、登录成功 User user = (User) subject.getPrincipal(); // 4、放入session session.put(SysConstant.CURRENT_USER_INFO, user); } catch (Exception e) { e.printStackTrace(); request.put("errorInfo", "用户名或密码错误!"); return "login"; } return SUCCESS;
在Shiro框架中,如果登陆失败,则会抛出异常,所有在使用Subject的代码外要使用try-catch,当捕获异常,表示用户身份验证失败。
以上就是Shiro安全框架的基本介绍,推荐看动力节点的Shiro入门教程自学的,非常详细,适合初学者
Shiro教程-Apache Shiro安全框架实战
https://www.bilibili.com/video/BV14T4y1g75M
Shiro资料下载
http://www.bjpowernode.com/?toutiao
realme和小米谁更超值,盘点两千价位段最值得买的机型今年开年以后,各大厂家开始在两千价位段发力,推出了多款性能体验不逊色于高端旗舰手机且性价比超高的机型,受到了广大年轻消费者的喜爱。今天我们就来盘点几款这个价位段的佼佼者,说不定你就
黑马全速奔跑,realme真我618销量第一名,高考助力活动同时开启高考进行时,也是众多考生检验成果的日子,在此也祝愿广大学子们金榜题名。而高考结束后,很多学子在忙着选专业填志愿的同时,也要开始为步入大学校园生活而做准备。手机作为必需品,就一定要选
科勒精选邀裘继戎与DirtyClass跨界共创声色艺无界敢拓新界的科勒精选品牌,携手跨界融合先锋裘继戎与破圈电音组合DirtyClass,共同打造敢酷敢发光的艺术灵感之作声色艺无界,以东方传统艺术赋能西方创新科技,以富有魅力的光影空间点
不一样的潮流,英菲尼迪是怎么诠释的?在大部分消费者的印象里,许多来自欧美的豪华汽车品牌知名度以及影响力都是很高的。相比起这些品牌,日系豪华品牌似乎只能算是年轻新贵,但是在日系豪华品牌中,英菲尼迪却是频繁被提及的一个独
彻底告别甲醛侵扰,戴森HP04为健康保驾护航眼瞅着五月还没到,不少地方就已经烈日当头。还没来得及好好体会羽绒服和短袖擦肩而过的日子,春天似乎就已经过去了。早在今年三月,不少地方就已经宣布了正式入夏的消息。所谓入夏,一般指的是
一边忙于生计,一边小孩在玩手机。教育给了手机值吗?在外面吃饭或者吃粉,经常可以看到店主老板操手忙个不停,而店里的一个角落时不时会见到一两个不大的小孩,拿着一个手机在不停的玩耍。看抖音,学段子,玩游戏,乐其中钱是赚了那么一点,而小孩
生活的气息晚上准备去车库拿点东西,路过小区楼下广场,好是一片热闹!小孩骑车,玩耍打闹。大人呢?拿这蒲扇,站着在广场或廊亭下,一边扇动着一边起劲的聊天,或是坐在阶梯上休息。超市健身房路灯还亮着
江湖是非千奇百怪什么是江湖就是一个有恩怨的地方,用金庸的话说,只要有人的地方就有恩怨,有恩怨就会有江湖,人就是江湖。笑傲江湖无论你武功再高,也有人说你是一文不值,狗屁不如,你可能会想那他呢?就由如
生活的气息晚上准备去车库拿点东西,路过小区楼下广场,好是一片热闹!小孩骑车,玩耍打闹。大人呢?拿这蒲扇,站着在广场或廊亭下,一边扇动着一边起劲的聊天,或是坐在阶梯上休息。超市健身房路灯还亮着
如何避免下水救人而身亡的悲剧再发生作者z益最近多处发生为救溺水者身亡事件,其中最引起关注的为重庆市8名学生在河滩处玩耍期间,一名学生失足落水,其余7人前去施救,造成施救学生全部落水身亡。想起我读大学期间,曾经在游泳
光触媒除甲醛真的有用吗?看完之后别再交智商税了新房装修完之后面临的一个问题就是除甲醛,由此也接触了几家除甲醛的专业公司,发现他们现在用的最多的一种方式就是光触媒除甲醛。但是光触媒除甲醛真的有用吗?接下来让我来为你科普一下。首先