Shiro-认证
发布日期:2021-07-12 08:49:18 浏览次数:6 分类:技术文章

本文共 5178 字,大约阅读时间需要 17 分钟。

认证流程:

1. 获取当前的 Subject. 调用 SecurityUtils.getSubject();

2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject 的 isAuthenticated()
3. 若没有被认证, 则把用户名和密码封装为 UsernamePasswordToken 对象
1). 创建一个表单页面
2). 把请求提交到 SpringMVC 的 Handler
3). 获取用户名和密码.
4. 执行登录: 调用 Subject 的 login(AuthenticationToken) 方法.
5. 自定义 Realm 的方法, 从数据库中获取对应的记录, 返回给 Shiro.
1). 实际上需要继承 org.apache.shiro.realm.AuthenticatingRealm 类
2). 实现 doGetAuthenticationInfo(AuthenticationToken) 方法.
6. 由 shiro 完成对密码的比对.

 

实现过程:

  创建一个login.jsp

  

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Insert title here

Login Page

username:
password:

 

登录成功后的list.jsp  包含登出按钮

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Insert title here

List Page

Logout

 

 

 

 创建一个Controller  ShiroHandler.java

package com.java.shiro.realms;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;@Controller@RequestMapping("/shiro")public class ShiroHandler {    @RequestMapping("/login")    public String login(@RequestParam("userName") String userName,            @RequestParam("password") String password) {        Subject currentUser = SecurityUtils.getSubject();        if (!currentUser.isAuthenticated()) {            UsernamePasswordToken token = new UsernamePasswordToken(userName,                    password);            token.setRememberMe(true);            try {                currentUser.login(token);            } catch (AuthenticationException e) {                System.out.println("登录失败:" + e.getMessage());            }        }        return "redirect:/list.jsp";    }}

 

创建一个Realm 重写AuthenticatingRealm 的doGetAuthenticationInfo()

package com.java.shiro.realms;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.realm.AuthenticatingRealm;public class ShiroRealm extends AuthenticatingRealm {    @Override    protected AuthenticationInfo doGetAuthenticationInfo(            AuthenticationToken token) throws AuthenticationException {        System.out.println("doGetAuthenticationInfo " + token);        // 1. 把AuthenticationToken 转换为UsernamePasswordToken        UsernamePasswordToken up = (UsernamePasswordToken) token;        // 2. 从UsernamePasswordToken 中来获取username        String username = up.getUsername();        // 3. 调用数据库的方法,从数据库中查询username对应的用户记录        System.out.println("从数据库中获取userName :" + username + " 所对应的用户信息.");        // 4. 若用户不存在,则可以抛出 UnknownAccoountException 异常        if ("unknown".equals(username)) {            throw new UnknownAccountException("用户不存在");        }        // 5. 根据用户信息的情况,决定是否需要抛出其他的AuthencationException 异常 假设用户被锁定        if ("monster".equals(username)) {            throw new LockedAccountException("用户被锁定");        }        // 6. 根据用户的情况,来构建AuthenticationInfo 对象并返回,通常使用的是        // SimpleAuthenticationInfo        // 以下信息是从数据库获取的.        Object principal = username; // principal 认证的实体信息.                                        // 可以是username,也可以是数据表对应的用户的实体类对象        String credentials = "123456"; // credentials:密码        String realmName = getName();        AuthenticationInfo info = new SimpleAuthenticationInfo(principal,                credentials, realmName);        return info;    }}

 

 

在applicationContext.xml 中添加对应的 过滤器

/login.jsp= anon /shiro/login= anon /shiro/logout = logout # everything else requires authentication: /** = authc

 

在登录成功后,点击后退,再次随便输入依旧能够登录成果,是由于缓存的作用。

 

密码的比对:

通过AuthenticatingRealm  的 credentialsMatcher 属性进行的比对

 

 credentialsMatcher 非常重要,因为在生产中数据库存的密码不会是一个明文的密码,会是一个加密后的密码,比对加密的密码也是通过credentialsMatcher 来进行比对

 

转载于:https://www.cnblogs.com/wq3435/p/6260483.html

转载地址:https://blog.csdn.net/ankan7400/article/details/102088935 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:ORACLE创建表空间、创建用户、更改用户默认表空间以及授权、查看权限
下一篇:Java基础-关于session的详细解释

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年03月13日 02时40分16秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

java socket udp 广播_1.Java 的屏幕广播(基于UDP),2.多线程下载器 2019-04-21
java控制热敏打印机的例子.rar_stm32控制热敏打印机 2019-04-21
java clone equals_(原)java中对象复制、==、equals 2019-04-21
php7 memcached.exe,PHP7 下安装 memcache 和 memcached 扩展 2019-04-21
计算机二级java技巧,计算机二级报java难考吗 2019-04-21
php foreach 数据库,php – 使用foreach将数据库检索的数据排列在HTML表中 2019-04-21
拉格朗日matlab编程例题,Matlab习题讲解.doc 2019-04-21
case是不是php语言关键字,PHP语言 switch 的一个注意点 2019-04-21
linux php mkdir失败,linux – mkdir错误:参数无效 2019-04-21
config.php渗透,phpMyAdmin 渗透利用总结 2019-04-21
java list 合并 重复的数据_Java ArrayList合并并删除重复数据3种方法 2019-04-21
android volley 上传图片 和参数,android - 使用android中的volley将图像上传到multipart中的服务器 - 堆栈内存溢出... 2019-04-21
android开发的取消清空按钮,Android开发实现带清空按钮的EditText示例 2019-04-21
android gp服务,ArcGIS Runtime SDK for Android开发之调用GP服务(异步调用) 2019-04-21
mysql整体会滚_滚mysql 2019-04-21
向mysql数据库中添加批量数据类型_使用JDBC在MySQL数据库中快速批量插入数据 2019-04-21
最全的mysql 5.7.13_最全的mysql 5.7.13 安装配置方法图文教程(linux) 强烈推荐! 2019-04-21
mssql连接mysql数据库文件_在本地 怎么远程连接MSSQL数据库 2019-04-21
mssql 远程无法连接mysql_解决SQLServer远程连接失败的问题 2019-04-21
linux mysql c++编程_Linux下进行MYSQL的C++编程起步手记 2019-04-21