JAVA|多Realm管理基础实现
1 前言
在shiro的使用实现中,会遇到一个问题,那就是用户和管理员的分别登录认证等,首先想到的就是只创建一个user表来存,并且给他们分别赋予不同的角色权限等。而下面要说的是另一个处理办法,那就是对于不同表的用户分别创建不同的Realm。下面就来具体看一下:
2 创建Realm
在这里创建了两个Realm作为例子(StudentRealm和AdminRealm),如图2.1
图2.1
上面展示的为AdminRealm,StudentRealm也为同理,继承AuthorizingRealm,并实现授权及认证,其中授权及认证就根据需要自行添加。
3 ShiroConfig配置
下面就是对ShiroConfig进行配置,首先就是引入这两个Realm:
@Bean(name = "studentRealm")
public StudentRealm studentRealm() {
return new StudentRealm();
}
@Bean(name = "adminRealm")
public AdminRealm adminRealm() {
return new AdminRealm();
}
接着编写shiro的DefaultWebSecurityManager,创建一个List集合,存入这两个Realm。注意:存单个Realm时用的是securityManager.setRealm(),而存多个时是securityManager.setRealms():
@Bean(name = "DefaultWebSecurityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
List<Realm> realms = new ArrayList<>();
realms.add(studentRealm());
realms.add(adminRealm());
securityManager.setRealms(realms);
return securityManager;
}
4 登录认证
最后就是对登录认证的编写,由于需要区分不同登录角色,所以首先就需要在前端页面加上选择的loginType,传不同的值过来,用于进行不同的认证:
图4.1
然后在写一个LoginToken类,继承UsernamePasswordToken,并且加入loginType的内容:
public class LoginToken extends UsernamePasswordToken {
private String loginType;
public LoginToken(final String username,
final String password,
final String loginType) {
super(username,password);
this.loginType = loginType;
}
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
}
最后一步就是对Controller层接口的编写,需要传id(username),password以及选择登录的角色(学生/管理员),if判断选择的是学生还是管理员,分别进行不同的认证以及页面跳转,下面是自己的一个例子,仅供参考:
@PostMapping(value = "/student_login")
public String Student(String id, String password, Model model, HttpSession session, String loginType) {
//shiro编写登录认证
//1.获取subject
Subject subject = SecurityUtils.getSubject();
//2.封装数据
LoginToken token = new LoginToken(String.valueOf(id), ShiroKit.md5(password, id), loginType);
//3.执行登录方法
try {
subject.login(token);
if (loginType.equals("student")) {
Student student = (Student) subject.getPrincipal();
//从userrealm里传过来的用户名拿到,把学生对象信息查出来,存入session
student = studentService.findByStuid((String) token.getPrincipal());
session.setAttribute("student",student);
return "redirect:/question/list1";
}
if (loginType.equals("admin")) {
Admin admin = (Admin) subject.getPrincipal();
session.setAttribute("admin", admin);
return "redirect:/question/add_question";
}
//有任何异常都是登录失败
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名不存在!");
return "register_login/login";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码错误!");
return "register_login/login";
}
return "";
}
5 总结
这里展示的是最基本的设置,还有其他需求或漏洞还需要按实际情况及需求解决。
- Android内存泄漏终极解决篇(下)
- 利用Volatility查找系统中的恶意DLL
- 雪人行动:利用IE10 0day漏洞的APT攻击剑指美国军方情报
- Android开发:最详细的 Toolbar 开发实践总结
- 关于yubikey对web应用的杞人之忧
- 利用旧版Android漏洞的E-Z-2-Use攻击代码已在Metasploit发布
- Android Studio你不知道的调试技巧
- Android 数据绑定框架DataBinding,堪称解决界面逻辑的黑科技
- 汽车黑客:没有Security就没有Safety
- Android 自定义View高级特效,神奇的贝塞尔曲线
- Android二维码扫描开发(一):实现思路与原理
- 说一道简单的BCTF题 – 分分钟而已
- 安全扫描工具Nmap引擎理解文档
- AppFuse项目笔记(1)
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- PyQt5 技术篇-控件长宽度、高度设置,组件大小设置,组件尺寸查看。
- python基本数据类型
- Python 技术篇-PyQt5动画功能演示,组件移动、尺寸改变动画演示
- 搭建k8s高可用集群 - 二进制方式
- DeepWalk:图网络与NLP的巧妙融合
- 基于kubeadm搭建k8s高可用集群
- 扑克牌例题与Collections工具类
- 快速了解Kubernetes
- PyQt5 技巧篇-按钮竖排显示方法,Qt Designer设置按钮竖排显示。
- Kafka集群监控、安全机制与最佳实践
- PyQt5 技术篇-设置输入框的placeholder方法,Qt Designer设置Line Edit、Text Edit编辑框的placeholder
- Kafka集群搭建及必知必会
- Python 技术篇-打开指定文件夹、目录、路径方法,运行指定文件演示
- Python 技巧篇-同一个方法多次引用不同效果功能实现,可选参数设置方法
- Kafka核心API——Connect API