Shiro--自定义Realm进行认证和授权 迈不过友情╰ 2021-08-24 12:52 723阅读 0赞 ### 创建Maven项目,引入依赖 ### <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- shrio依赖 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.4.1</version> </dependency> <!--用于slf4j与log4j2保持桥接 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.12.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.1</version> </dependency> </dependencies> log4j2.xml: <?xml version="1.0" encoding="UTF-8"?> <configuration> <!--先定义所有的appender--> <appenders> <!--输出控制台的配置--> <console name="Console" target="SYSTEM_OUT"> <!--输出日志的格式--> <!--<patternlayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%p] %c %m %n"/>--> <patternlayout pattern="[%p] %m %n"/> </console> </appenders> <!-- 然后定义logger,只有定义了logger并引入的appender,appender才会生效--> <!-- 日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <loggers> <root level="DEBUG"> <!--输出到控制台--> <appender-ref ref="Console"/> </root> <!--org.springframework <logger name="org.springframework" level="INFO"/>--> </loggers> </configuration> ### User.class ### public class User { private String username; private String password; private Integer status; // 用户状态 0: 正常 1:禁用 2:锁定 public User(String username, String password,Integer status) { this.username = username; this.password = password; this.status = status; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } } ### ShiroUtil.class ### public class ShiroUtil { /** * 初始化shiro运行环境 */ static { //1.初始化shiro的安全管理器 DefaultSecurityManager securityManager = new DefaultSecurityManager(); //2.设置用户的权限信息到安全管理器 //Realm realm = new IniRealm("classpath:shiro.ini"); Realm realm = new ShiroRealm(); securityManager.setRealm(realm); //3. 使用SecurityUtils将securityManager设置到运行环境中 SecurityUtils.setSecurityManager(securityManager); } public static Subject login(String username,String password) { //1. 创建一个Subject实例 Subject subject = SecurityUtils.getSubject(); //2. 创建用于认证的认证的token,记录用户认证的身份和凭证即账号和密码 AuthenticationToken token = new UsernamePasswordToken(username, password); //3.主体要进行登录,登录的时候进行认证检查 subject.login(token); return subject; } } ### 自定义Realm继承AuthorizingRealm ### public class ShiroRealm extends AuthorizingRealm { /** * 登录认证 * * @param authenticationToken * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; // 1.获取用户输入的用户名 String username = token.getUsername(); // 2.获取用户输入的密码 String password = new String(token.getPassword()); // 3.根据用户名去DB查询对应的用户信息 User user = new User("admin", "123456", 0); if (!user.getUsername().equals(username)) { throw new UnknownAccountException("用户名不存在"); } if (!user.getPassword().equals(password)) { throw new CredentialsException("密码错误"); } if (user.getStatus() == 1) { throw new DisabledAccountException("账号被禁用"); } if (user.getStatus() == 2) { throw new LockedAccountException("账号被锁定"); } System.out.println("认证成功..."); // 创建简单认证信息对象 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(token.getPrincipal(), token.getCredentials(), getName()); return info; } /** * 授权 * 将认证通过的用户的角色和权限信息设置到对应用户主体上 * * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = principals.getPrimaryPrincipal().toString(); //模拟从数据库获取当前用户的角色 通过用户名查询该用户拥有的角色名称 Set<String> roleNameSet = new HashSet<>(); roleNameSet.add("系统管理员"); //roleNameSet.add("系统运维"); //模拟从数据库获取当前用户的权限 通过用户名查询该用户拥有的权限名称 Set<String> permissionNameSet = new HashSet<>(); permissionNameSet.add("sys:user:list"); // 查看列表 permissionNameSet.add("sys:user:info"); // 查看用户详情 permissionNameSet.add("sys:user:create");// 创建用户 permissionNameSet.add("sys:user:update");// 修改用户 permissionNameSet.add("sys:user:delete");// 删除用户 // 简单授权信息对象,对象中包含用户的角色和权限信息 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRoles(roleNameSet); info.addStringPermissions(permissionNameSet); System.out.println("授权完成...."); return info; } } ### 测试 ### @Test public void test02() { // 登录认证 Subject subject = ShiroUtil.login("admin", "123456"); // 授权资源检查 // 模拟当前用户点击了 <新增用户> 按钮,检查该用户时候拥有新增用户的权限 System.out.println("检查该用户时候拥有新增用户的权限:" + subject.isPermitted("sys:user:create")); System.out.println("检查该用户时候拥有新增角色的权限:" + subject.isPermitted("sys:role:create")); System.out.println("检查该用户是否是系统管理员角色:" + subject.hasRole("系统管理员")); System.out.println("检查该用户是否是系统运维角色:" + subject.hasRole("系统运维")); // 退出系统 subject.logout(); } 控制台输出: 认证成功... [DEBUG] Looked up AuthenticationInfo [admin] from doGetAuthenticationInfo [DEBUG] AuthenticationInfo caching is disabled for info [admin]. Submitted token: [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. [DEBUG] Performing credentials equality check for tokenCredentials of type [[C and accountCredentials of type [[C] [DEBUG] Both credentials arguments can be easily converted to byte arrays. Performing array equals comparison [DEBUG] Authentication successful for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false]. Returned account [admin] [DEBUG] No sessionValidationScheduler set. Attempting to create default instance. [INFO] Enabling session validation scheduler... [DEBUG] Creating new EIS record for new session instance [org.apache.shiro.session.mgt.SimpleSession,id=null] [DEBUG] No authorizationCache instance set. Checking for a cacheManager... [DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained. 授权完成.... 检查该用户时候拥有新增用户的权限:true [DEBUG] No authorizationCache instance set. Checking for a cacheManager... [DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained. 授权完成.... 检查该用户时候拥有新增角色的权限:false [DEBUG] No authorizationCache instance set. Checking for a cacheManager... [DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained. 授权完成.... 检查该用户是否是系统管理员角色:true [DEBUG] No authorizationCache instance set. Checking for a cacheManager... [DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained. 授权完成.... 检查该用户是否是系统运维角色:false [DEBUG] Logging out subject with primary principal admin [DEBUG] No authorizationCache instance set. Checking for a cacheManager... [DEBUG] No cache or cacheManager properties have been set. Authorization cache cannot be obtained. [DEBUG] Stopping session with id [fc5a25ba-fd10-482d-9262-f033f724df05]
还没有评论,来说两句吧...