用户登录安全框架shiro—用户的认证和授权(一)
ssm整合shiro框架,对用户的登录操作进行认证和授权,目的很纯粹就是为了增加系统的安全线,至少不要输在门槛上嘛。
这几天在公司独立开发一个供公司内部人员使用的小管理系统,客户不多但是登录一直都是简单的校验查询,没有使用任何安全框架来保驾护航,下午终于拿出以前的手段来完善了一下,将shiro安全框架与ssm整合使用的步骤和大家分享一下,都是些简单易懂的东西,希望努力没有白费,帮到大家。
ssm整合shiro安全框架的步骤:
1、引入shiro安全框架的所需jar包
1 <!-- shiro -->
2 <dependency>
3 <groupId>org.apache.shiro</groupId>
4 <artifactId>shiro-core</artifactId>
5 <version>1.2.3</version>
6 </dependency>
7 <dependency>
8 <groupId>org.apache.shiro</groupId>
9 <artifactId>shiro-spring</artifactId>
10 <version>1.2.3</version>
11 </dependency>
12 <dependency>
13 <groupId>org.apache.shiro</groupId>
14 <artifactId>shiro-web</artifactId>
15 <version>1.2.3</version>
16 </dependency>
17 <dependency>
18 <groupId>org.apache.shiro</groupId>
19 <artifactId>shiro-ehcache</artifactId>
20 <version>1.2.3</version>
21 </dependency>
2、在web.xml文件中配置shiro拦截器
1 <!-- spring整合安全框架 -->
2 <filter>
3 <filter-name>DelegatingFilterProxy</filter-name>
4 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
5 <!-- 初始化参数 -->
6 <init-param>
7 <param-name>targetBeanName</param-name>
8 <param-value>shiroFilter</param-value>
9 </init-param>
10 </filter>
11 <filter-mapping>
12 <filter-name>DelegatingFilterProxy</filter-name>
13 <url-pattern>/*</url-pattern>
14 </filter-mapping>
3、创建spring整合shiro安全框架的配置文件applicationContext-shiro.xml(各位在拷贝的时候记得修改一下跳转连接地址)
1 <!-- shiro开启事务注解 -->
2 <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
3 <property name="securityManager" ref="securityManager" />
4 </bean>
5
6 <!--
7 /** 除了已经设置的其他路径的认证
8 -->
9 <!-- shiro工厂bean配置 -->
10 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
11 <!-- shiro的核心安全接口 -->
12 <property name="securityManager" ref="securityManager"></property>
13 <!-- 要求登录时的连接 -->
14 <property name="loginUrl" value="/login.jsp"></property>
15 <!-- 登录成功后要跳转的连接(此处已经在登录中处理了) -->
16 <!-- <property name="successUrl" value="/index.jsp"></property> -->
17 <!-- 未认证时要跳转的连接 -->
18 <property name="unauthorizedUrl" value="/refuse.jsp"></property>
19 <!-- shiro连接约束配置 -->
20 <property name="filterChainDefinitions">
21 <value>
22 <!-- 对静态资源设置允许匿名访问 -->
23 /images/** = anon
24 /js/** = anon
25 /css/** = anon
26 <!-- 可匿名访问路径,例如:验证码、登录连接、退出连接等 -->
27 /auth/login = anon
28 <!-- 剩余其他路径,必须认证通过才可以访问 -->
29 /** = authc
30 </value>
31 </property>
32 </bean>
33
34 <!-- 配置shiro安全管理器 -->
35 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
36 <property name="realms" ref="customRealm"></property>
37 </bean>
38
39 <!-- 自定义Realm -->
40 <bean id="customRealm" class="com.zxz.auth.realm.UserRealm">
41 <property name="credentialsMatcher" ref="credentialsMatcher"></property>
42 </bean>
43
44 <!-- 配置凭证算法匹配器 -->
45 <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
46 <!-- Md5算法 -->
47 <property name="hashAlgorithmName" value="Md5"></property>
48 </bean>
【高能说明:以上俩个配置文件中加粗画线的红色部分必须一致,没毛病。】
还需要说明的是,在上面的配置文件中shiro连接约束配置那块,要特别小心,哥们我就在哪块吃了2天的折磨亏,当时是只配置了/** = authc,没有配置可匿名访问的路径,当时是什么情况吧,就是无限次的调试无限次的修改,我是真长记性了,还有一点就是在配置的时候把你项目中的静态资源放开,被屏蔽了啊,好心提醒,不谢。
4、当然,在这之前,还要编写自定义realm类,该类必须认AuthorizingRealm类做爸爸,不然你是不行滴,之后还有俩个儿子需要处理了,一个是认证另一个授权,理论我就不多说了,MD没用。
1 public class UserRealm extends AuthorizingRealm {
2
3 @Autowired
4 private UserService userService;
5
6 @Override
7 public String getName() {
8 return "customRealm";
9 }
10
11 /**
12 * 认证
13 */
14 @Override
15 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
16 // 获取用户名称
17 String username = (String) token.getPrincipal();
18 User user = userService.findByUsername(username);
19 if (user == null) {
20 // 用户名不存在抛出异常
21 System.out.println("认证:当前登录的用户不存在");
22 throw new UnknownAccountException();
23 }
24 String pwd = user.getPassword();
25 return new SimpleAuthenticationInfo(user, pwd, getName());
26 }
27
28 /**
29 * 授权
30 */
31 @Override
32 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection princ) {
33 return null;
34 }
35 }
5、到这儿,shiro安全框架的整合是完成了,然后编写action类来实现登录功能,不多说了,直接上代码。
1 /**
2 * shiro框架登录
3 * @param user
4 */
5 @RequestMapping(value = "/login",method=RequestMethod.POST)
6 public ModelAndView login(User user){
7 // 表面校验
8 if(!StringUtil.isNullOrBlank(user.getUsername()) || !StringUtil.isNullOrBlank(user.getPassword())){
9 return new ModelAndView("login")
10 .addObject("message", "账号或密码不能为空")
11 .addObject("failuser", user);
12 }
13 // 获取主体
14 Subject subject = SecurityUtils.getSubject();
15 try{
16 // 调用安全认证框架的登录方法
17 subject.login(new UsernamePasswordToken(user.getUsername(), user.getPassword()));
18 }catch(AuthenticationException ex){
19 System.out.println("登陆失败: " + ex.getMessage());
20 return new ModelAndView("login")
21 .addObject("message", "用户不存在")
22 .addObject("failuser", user);
23 }
24 // 登录成功后重定向到首页
25 return new ModelAndView("redirect:/index");
26 }
最后需要给大家说的就是,当某用户登录成功之后,shiro安全框架就会将用户的信息存放在session中,你可以通过User user = (User) SecurityUtils.getSubject().getPrincipal();这句代码在任何地方任何时候都能获取当前登录成功的用户信息。
很长年间没用shiro安全框架了,原理忘得都差不多了,但是驾驭它还是没问题的,如果哪儿写的不对的,希望各位指教,尽管我脾气很爆,哈哈哈。
- 学js少看书肯定是不成的,要多看。
- 抽象是啥?就是一群人的特征;js中的call是啥?就是我想用你家的电饭锅
- 从node事件到观察者 -- 学习要有一根线索
- Joy:一款用于捕获和分析网络内部流量数据的工具
- 老尚,能讲讲闭包么?“可以,没问题,马上”
- PHP代码安全杂谈
- angularJs,请问vue是你失散多年的亲人吗?
- 无监督学习神经网络——自编码
- 不学不知道,sort()方法中的坑
- js数组去重的思路与缓动公式
- vue.js 的组件感觉比react的直观&&面试相关的七个实例
- 前端组件“可编辑表格”,怎么设计才好呢?先得有思路
- Linux基础(day61)
- 一款名为Rapid的勒索软件正在迅速传播
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 微信小程序webview,a锚点跳转,回退时一直保留在原页面
- SLURM使用教程
- MIME 类型大全,你值得收藏
- Jetbrains系列---PyCharm, Goland翻译插件推荐Translation
- 熬夜总结了 “HTML5画布” 的知识点(共10条)
- 在PyTorch中使用深度自编码器实现图像重建
- Django+Vue开发生鲜电商平台之9.个人中心功能开发
- Serverless 实战:通过 Component 实现多地域部署容灾
- SQL 行转列+窗口函数的实例
- 回答一下这 10 个最常见的 Javascript 问题
- 千万级数据表选错索引导致的线上慢查询事故
- 递归优化
- Webshell 高级样本收集
- 处理Sprint Boot与Storm1.2.2日志实现的冲突,使用logback记录日志
- Docker 命令总结