之五 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";}}

推薦閱讀