SpringBoot集成Shiro实现权限管理的案例:
一 首先设计表结构,可以使用用户表、权限表、角色表、角色权限表、用户角色表。通过赋予用户不同角色来实现权限控制。
1 权限表:
@Entity
@Data
public class Perssion {
@Id@GeneratedValue
private int id;
private String perssionname;
private String restype;
private int parentid;
private String url;
}
2 用户表:
@Entity
@Data
public class User {
@Id@GeneratedValue
private int id;
private String username;
private String password;
}
3 角色表:
@Entity
@Data
public class Role {
@Id
@GeneratedValue
private int id;
private String rolename;
}
4 角色权限表:
@Entity
@Data
public class RolePerssion {
@Id
@GeneratedValue
private int id;
private int rid;
private int pid;
}
5 用户角色表:
@Entity
@Data
public class UserRole {
@Id
@GeneratedValue
private int id;
private int uid;
private int rid;
}
配置文件:
spring:
datasource:
url: jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: root
#schema: database/import.sql
#sql-script-encoding: utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL5Dialect
thymeleaf:
cache: false
mode: HTML
二 编写Dao层查询用户角色和角色权限的接口:
public interface RoleDao extends JpaRepository<UserRole,Integer> {//通过用户id查询所拥有的角色
List<UserRole> findRoleByUid(int uid);
}
public interface RolePerssionDao extends JpaRepository<RolePerssion,Integer> {
//通过角色id查询所对应的权限
public List<RolePerssion> findRolePerssionByRid(int rid);
}
三 编写业务层代码:(业务层接口此处省略)
@Service
public class RoleServiceImpl implements RoleService {//查询用户角色业务层
@Autowired
RoleDao roleDao;
@Override
public List<UserRole> findRoleByUid(int uid) {
return roleDao.findRoleByUid(uid);
}
}
@Service
public class RolePerssionImpl implements RolePerssionService {//查询角色权限业务层
@Autowired
RolePerssionDao rolePerssionDao;
@Override
public List<RolePerssion> findRolePerssion(int rid) {
return rolePerssionDao.findRolePerssionByRid(rid);
}
}
以上只是简单的查询角色权限,用户角色的功能代码:
五 下面开始整合Shiro:
package com.irootech.config;
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;
/**
* @author anping.tan
* @date 2019/7/26 19:15
*/
public class UserInfoRealm extends AuthorizingRealm {
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken token= (UsernamePasswordToken) authenticationToken;
String username=token.getUsername();
System.out.println("用户姓名:"+username+"=====");
String password="a";//假设登录用户密码为a,数据库查询出来为a
//User user=业务层通过username查询数据库判断用户是否存在 不存在直接return
SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(username,password,getName());//password为从数据查询出来的password
return simpleAuthenticationInfo;
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
Object username=principalCollection.getPrimaryPrincipal();
System.out.println(username+"登录用户权限查询");
//查询出username拥有的角色和权限
simpleAuthorizationInfo.addStringPermission("1"); //这里给所有用户添加1和2的权限,d但是数据库必须有1和2权限
simpleAuthorizationInfo.addStringPermission("2");
return simpleAuthorizationInfo;
}
}
package com.irootech.config;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* @author anping.tan
* @date 2019/7/26 19:27
*/
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean get(SecurityManager securityManager){
ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
Map map=new HashMap();
map.put("/static/**","anon");
map.put("/**","authc");
map.put("/index","anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
shiroFilterFactoryBean.setLoginUrl("/tologin.action");
shiroFilterFactoryBean.setSuccessUrl("/success.action");
shiroFilterFactoryBean.setUnauthorizedUrl("/403.action");
return shiroFilterFactoryBean;
}
@Bean
public UserInfoRealm ge(){
UserInfoRealm userInfoRealm=new UserInfoRealm();
return userInfoRealm;
}
@Bean
public SecurityManager gest(UserInfoRealm userInfoRealm){
DefaultSecurityManager defaultSecurityManager=new DefaultWebSecurityManager();
defaultSecurityManager.setRealm(userInfoRealm);
return defaultSecurityManager;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver
createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("UnauthorizedException","403");
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("ex"); // Default is "exception"
//r.setWarnLogCategory("example.MvcLogger"); // No default
return r;
}
}
六 编写控制层代码:
@Controller
public class RoleController {
@Autowired
RoleService roleService;
@Autowired
RolePerssionService rolePerssionService;
@RequestMapping("/findRoleByUid.action")
@ResponseBody
public List<UserRole> findRoleByUid(int uid){
for(UserRole role: roleService.findRoleByUid(uid)){
System.out.println("角色id:"+role.getRid());
}
return roleService.findRoleByUid(uid);
}
@RequestMapping("/findRolePerssionByRid.action")
@ResponseBody
public List<RolePerssion> findRolePerssionByRid(int rid){
for(RolePerssion rolePerssion:rolePerssionService.findRolePerssion(rid)){
System.out.println("权限id:"+rolePerssion.getPid());
}
return rolePerssionService.findRolePerssion(rid);
}
@RequestMapping("/add.action")
@RequiresPermissions("1")
public String add(){
System.out.println("添加");
return "add";
}
@RequestMapping("/delete.action")
@RequiresPermissions("3")
public String delete(){
System.out.println("删除");
return "del";
}
@RequestMapping("/tologin.action")
public String tologin(HttpServletRequest request,Map<String,Object> map){
// 登录失败从request中获取shiro处理的异常信息。
// shiroLoginFailure:就是shiro异常类的全类名.
String exception = (String) request.getAttribute("shiroLoginFailure");
System.out.println("异常"+exception);
if(IncorrectCredentialsException.class.getName().equals(exception)){
System.out.println("密码不正确");
map.put("msg","密码不正确");
}
return "login";
}
@RequestMapping("/login.action")
public String login(HttpServletRequest request){
String exception=request.getParameter("shiroLoginFailure");
System.out.println("异常"+exception);
if(IncorrectCredentialsException.class.getName().equals(exception)){
return "error";
}
return "success";
}
@RequestMapping("/403.action")
public String unfind(){
return "403";
}
@RequestMapping("/success.action")
public String success(){
return "success";
}
@RequestMapping("/update.action")
@RequiresPermissions("2")
public String update(){
return "update";
}
}