Shiro
shiro指的是权限管理
shiro需要添加的依赖(需要注意的是如果遇到提醒发行版本为5,运行不了,需要进行以下修改)
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.22</version> <scope>provided</scope> </dependency>
1.在 Java SE 环境基于内置 IniRealm 使用 Shiro 完成认证。
第一,在resource下创建shiro-authc.ini文件(需要注意的是【user】如果是【User】的话或i者不写会报找不到账号异常)
#用户的身份、凭据 [users] zhangsan=555 lanxw=666
第二步,调用测试类测试
@Test public void test1(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); IniRealm iniRealm = new IniRealm("classpath:shiro-authc.ini"); securityManager.setRealm(iniRealm); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); System.out.println("认证状态:"+subject.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("lanxw", "666"); subject.login(token); System.out.println("认证状态:"+subject.isAuthenticated()); subject.logout(); System.out.println("认证状态:"+subject.isAuthenticated());
2.在 Java SE 环境基于自定义 Realm 使用 Shiro 完成认证。
第一,创建User类对用户名和密码进行封装
public class User { private String username; private String password; }
第二创建DataMapper
public class DataMapper { private static Map<String, User> userData = new HashMap<String, User>(); static{ //初始化数据 User u1 = new User("lanxw","666"); User u2 = new User("yl","888"); userData.put(u1.getUsername(),u1); userData.put(u2.getUsername(),u2); } //提供静态方法,模拟数据库返回数据 public static User getUserByName(String username){ return userData.get(username); } }
第三创建自定义Realm
public class UserRealm extends AuthorizingRealm { //提供认证信息 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //页面传入的账号 String userName = (String) token.getPrincipal(); //模拟从数据库中查询数据 User user = DataMapper.getUserByName(userName); if(user==null){ //账号不存在则返回NULL return null; }else{ //如果存在需要封装成AuthenticationInfo对象返回 return new SimpleAuthenticationInfo( user,身份对象,可以理解为在Web环境中登录成功后需要放入Session中的对象 user.getPassword(),//凭证(密码),需要和传入的凭证(密码)做比对 this.getName());//当前 Realm 的名称,暂时无用,不需纠结 } } //提供授权信息,此次实验暂时用不到 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } }
第四测试类
@Test public void test2(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); securityManager.setRealm(new UserRealm()); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); System.out.println("认证状态:"+subject.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("lanxw", "666"); subject.login(token); System.out.println("认证状态:"+subject.isAuthenticated()); subject.logout(); System.out.println("认证状态:"+subject.isAuthenticated()); }
3.在 Java SE 环境基于内置 IniRealm 使用 Shiro 完成授权。
第一,在resource下创建shiro-authc.ini文件
#用户的身份、凭据、角色 [users] yl=888,hr,seller lanxw=666,seller #角色与权限信息 [roles] hr=user:list,user:delete seller=customer:list,customer:save
第二,创建测试类
@Test public void test3(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); IniRealm iniRealm = new IniRealm("classpath:shiro-authc.ini"); securityManager.setRealm(iniRealm); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); System.out.println("认证状态:"+subject.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("lanxw", "666"); subject.login(token); System.out.println("认证状态:"+subject.isAuthenticated()); // subject.logout(); // System.out.println("认证状态:"+subject.isAuthenticated()); System.out.println("是否有hr" + subject.hasRole("hr")); System.out.println("是否有销售员" + subject.hasRole("seller")); subject.checkRole("seller"); System.out.println("是否有删除权限" + subject.isPermitted("user:delete")); subject.checkPermission("customer:list"); }
在 Java SE 环境基于自定义 Realm 使用 Shiro 完成授权。
第一步修改DataMapper和test,在DataMapper中新增两个方法和两个字段roleData,permissionData,getUsernameByRole和getUSernameByPermission
public class DataMapper { //用户集合 private static Map<String, User> userData = new HashMap<String, User>(); //角色集合 private static Map<String, List<String>> roleData = new HashMap<String, List<String>>(); //权限集合 private static Map<String, List<String>> permissionData = new HashMap<String, List<String>>(); static{ //初始化用户数据 User u1 = new User("lanxw","666"); userData.put(u1.getUsername(),u1); roleData.put(u1.getUsername(), Arrays.asList("seller")); permissionData.put(u1.getUsername(), Arrays.asList("customer:list","customer:save")); User u2 = new User("yl","888"); userData.put(u2.getUsername(),u2); roleData.put(u2.getUsername(), Arrays.asList("seller","hr")); permissionData.put(u1.getUsername(), Arrays.asList("customer:list","customer:save","user:list","user:delete")); } //提供静态方法,模拟数据库返回数据 public static User getUserByName(String username){ return userData.get(username); } public static List<String> getRoleByName(String username){ return roleData.get(username); } public static List<String> getPermissionByName(String username){ return permissionData.get(username); } }
修改测试类
@Test public void test4(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); // IniRealm iniRealm = new IniRealm("classpath:shiro-authc.ini"); securityManager.setRealm(new UserRealm()); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); System.out.println("认证状态:"+subject.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("lanxm", "666"); subject.login(token); System.out.println("认证状态:"+subject.isAuthenticated()); // subject.logout(); // System.out.println("认证状态:"+subject.isAuthenticated()); System.out.println("是否有hr" + subject.hasRole("hr")); System.out.println("是否有销售员" + subject.hasRole("seller")); System.out.println("是否同时拥有seller和hr两种角色" + subject.hasAllRoles(Arrays.asList("seller", "hr"))); subject.checkRole("seller"); System.out.println("是否有删除权限" + subject.isPermitted("user:delete")); subject.checkPermission("customer:list"); }
在 Java SE 环境基于自定义 Realm 使用 Shiro 完成认证,且要求存储的用户密码是加密的。
第一步在User类中增加一个字段salt(盐),这个表示在我们本来的密码基础上加上另外的密码,配合MD5来对原本的密码进行加密
第二步使用测试类,来对我们本来的密码进行加密,得来的密码拿到DataMapper中进行封装,第一个参数是原来的密码,第二个参数是密文,第三个参数是加密次数
第三步,进行测试来验证到底加密成功了没有
@Test public void test5(){ DefaultSecurityManager securityManager = new DefaultSecurityManager(); UserRealm userRealm = new UserRealm(); HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("md5"); matcher.setHashIterations(5); userRealm.setCredentialsMatcher(matcher); // IniRealm iniRealm = new IniRealm("classpath:shiro-authc.ini"); securityManager.setRealm(userRealm); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); System.out.println("认证状态:"+subject.isAuthenticated()); UsernamePasswordToken token = new UsernamePasswordToken("lanxm", "666"); subject.login(token); System.out.println("认证状态:"+subject.isAuthenticated());