之五 2流高手速成记:Springboot整合Shiro实现安全管理( 二 )

package com.example.hellospringboot.service;import com.example.hellospringboot.model.Permission;import java.util.List;public interface PermissionService {List<Permission> findPermissionsByRoleId(int roleId);}package com.example.hellospringboot.service.impl;import com.baomidou.mybatisplus.core.conditions.Wrapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.example.hellospringboot.mapper.PermissionMapper;import com.example.hellospringboot.model.Permission;import com.example.hellospringboot.service.PermissionService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class PermissionServiceImpl implements PermissionService {@AutowiredPermissionMapper mapper;public List<Permission> findPermissionsByRoleId(int roleId){QueryWrapper<Permission> wrapper = new QueryWrapper<>();wrapper = wrapper.eq("role_id", roleId);List<Permission> list = mapper.selectList(wrapper);return list;}}ok,我们已经准备好了所有的安全数据,及对应的读取方法
到这里,我们就算是做好了所有的准备工作
接下来看我们如何通过Shiro框架来运用这些已经装配好的枪炮子弹
4. 引入Shiro框架相关依赖(pom.xml)<!-- 引入shiro框架依赖 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.10.0</version></dependency>这次pom.xml终于不是第一步了,哈哈哈 。。。
5. 创建Realm嫁接Shiro框架及安全数据(realm/MyAuthorizingRealm)package com.example.hellospringboot.realm;import com.example.hellospringboot.model.Permission;import com.example.hellospringboot.model.Role;import com.example.hellospringboot.model.User;import com.example.hellospringboot.service.PermissionService;import com.example.hellospringboot.service.RoleService;import com.example.hellospringboot.service.UserService;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import java.util.HashSet;import java.util.List;import java.util.Set;public class MyAuthorizingRealm extends AuthorizingRealm {@AutowiredUserService userService;@AutowiredRoleService roleService;@AutowiredPermissionService permissionService;@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) {UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;String userName = token.getUsername();String passWord = String.valueOf(token.getPassword());if (!userService.checkUserByUsernameAndPassword(userName, passWord)) {//判断用户账号是否正确throw new UnknownAccountException("用户名或密码错误!");}return new SimpleAuthenticationInfo(userName, passWord, getName());}@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();String userName = principalCollection.getPrimaryPrincipal().toString();User user = userService.findUserByUserName(userName);if (user == null) {throw new UnknownAccountException("用户名或密码错误!");}List<Integer> rolesList = user.rolesList();Set<String> roles = new HashSet<>();Set<String> permissions = new HashSet<>();for (Integer roleId : rolesList) {Role role = roleService.findRoleById(roleId);roles.add(role.getName());List<Permission> permissionList = permissionService.findPermissionsByRoleId(roleId);for (Permission permission : permissionList) {permissions.add(permission.getName());}}info.setRoles(roles);info.setStringPermissions(permissions);return info;}}Realm的创建对于整个Shiro安全验证体系搭建而言是至关重要的一步!
其中两个抽象方法

doGetAuthenticationInfo —— 用于校验用户名及密码的合法性
doGetAuthorizationInfo —— 用于赋予实体对应的角色及交互权限
6. 测试用Controller创建package com.example.hellospringboot.controller;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.subject.Subject;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping("/user")@RestControllerpublic class UserController {@PostMapping("/login")public String login(String user, String pass) {UsernamePasswordToken token = new UsernamePasswordToken(user, pass);Subject subject = SecurityUtils.getSubject();if(!subject.isAuthenticated()) {try {subject.login(token);} catch (AuthenticationException e) {return e.getMessage();}}return "ok";}@PostMapping("/logout")public String logout(){Subject subject = SecurityUtils.getSubject();if(subject.isAuthenticated()) {try {subject.logout();} catch (AuthenticationException e) {return e.getMessage();}}return "ok";}@GetMapping("/admin")public String admin() {return "admin";}@GetMapping("/user")public String user() {return "user";}}

推荐阅读