通过shiro安全框架,学习实现登录,权限管理等操作。
先尝试简单的匹配用户、角色和权限操作。
0.导入对应jar包
1.创建shiro.ini 配置文件,在文件内定义用户、角色、权限等
#定义用户,用户名,密码、角色
[users]
tom = 123 , Admin
cat = 456 , ProductManager
#定义角色所对应权限
[roles]
Admin = *
#管理员拥有所有权限
ProducManager = addProduct,deleteProduct,updateProduct,listProduct
#产品经理对应产品权限
OrderManager = addOrder,deleteOrder,updateOrder,listOrder
2.创建用户类User'.java
同时实现对应getset方法
package hut;
public class User {
private String user_name;
private String user_password;
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getUser_password() {
return user_password;
}
public void setUser_password(String user_password) {
this.user_password = user_password;
}
}
3.建立测试类Test.java
package hut;
import java.util.ArrayList;
import java.util.List;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
public class Test {
public static void main(String args[]) {
//用户数据
User tom = new User();
tom.setUser_name("tom");
tom.setUser_password("123");
User cat = new User();
cat.setUser_name("cat");
cat.setUser_password("456");
User nobody = new User();
nobody.setUser_name("nobody");
nobody.setUser_password("789");
//用户们
List<User> users = new ArrayList<>();
users.add(tom);
users.add(cat);
users.add(nobody);
//角色数据
String roleadminString = "Admin";
String roleProductManager = "ProductManager";
//角色们
List<String> roles = new ArrayList<>();
roles.add(roleadminString);
roles.add(roleProductManager);
//权限们
String permitaddProduct = "addProduct";
String permitaddOrder = "addOrder";
List<String> permits = new ArrayList<>();
permits.add(permitaddOrder);
permits.add(permitaddProduct);
/*
数据导入完成,进行登录操作
* 登录每个用户
*/
for(User user : users) {
if(login(user)) {
System.out.printf("%s 成功登陆,用的密码是 %s %n",user.getUser_name(),user.getUser_password());
}
else {
System.out.printf("%s 成功失败,用的密码是 %s %n",user.getUser_name(),user.getUser_password());
}
}
/**
* 判断能够登录的用户是否拥有某个角色
*
*/
for(User user:users){
for(String role : roles) {
if(login(user)) {
if (hasRole(user,role)) {
System.out.printf("%s 拥有角色: %s %n",user.getUser_name(),role);
}
else {
System.out.printf("%s 不拥有角色: %s %n",user.getUser_name(),role);
}
}
}
}
for(User user:users) {
for(String permit:permits) {
if(login(user)) {
if(isPertimmed(user,permit)) {
System.out.printf("%s 拥有权限: %s %n",user.getUser_name(),permit);
}else {
System.out.printf("%s 不拥有权限: %s %n",user.getUser_name(),permit);
}
}
}
}
}
private static boolean hasRole(User user , String role) {
Subject subject = getSubject(user);
return subject.hasRole(role);
}
private static boolean isPertimmed(User user,String permit) {
Subject subject = getSubject(user);
return subject.isPermitted(permit);
}
private static Subject getSubject(User user){
//Subject,在shiro下就是当前用户
//获取默认安全管理者实例,获取本地资源文件,设置realm为本地资源文件
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
IniRealm iniRealm = new IniRealm("classpath:shiro.ini");
defaultSecurityManager.setRealm(iniRealm);
//将安全管理者放入全局对象
SecurityUtils.setSecurityManager(defaultSecurityManager);
//全局对象通过安全管理者生成Subject对象
Subject subject = SecurityUtils.getSubject();
return subject;
}
private static boolean login(User user) {
Subject subject = getSubject(user);
//如果已经登录过了,就进行退出
if(subject.isAuthenticated()) {
subject.logout();
}
//封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(user.getUser_name(),user.getUser_password());
try {
//将用户数据token,最终传入Realm中进行比对
subject.login(token);
} catch (AuthenticationException e) {
// TODO: handle exception
//验证错误
return false;
}
return subject.isAuthenticated();
}
}
~在private static Subject getSubject(User user)方法中,配置subject对象,将shiro.ini配置文件导入,获取默认安全
管理者实例,设置realm为本地资源文件,同时放入全局对象,生成subject对象。
~在private static boolean login(User user)方法中,实现登录功能,并封装用户数据,通过 UsernamePasswordToken
方法,将用户数据token与Realm中进行比对验证登录。
通过遍历,用subject对象的hasrole和ispermitted,判断是否拥有对应角色和权限。
编译运行: