SpringBoot整合Shiro及简单实现
创建SpringBoot项目
创建略
添加依赖
1.添加thymeleaf
<!-- thymeleaf相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2.添加mybatis
<!-- mybatis的相关依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.27</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
配置Shiro(重点)
创建Shiro的配置类ShiroConfig
- ShiroConfig配置类上添加@COnfiguration注解表明这是一个配置类
- 首先需要配置三个Bean分别为:ShiroFilterFactoryBean,DefaultWebSecurityManager,UserRealm
- ShiroFilterFactoryBean依赖于DefaultWebSecurityManager,DefaultWebSecurityManager依赖于UserRealm
- 自定义Realm:extends AuthorizingRealm,重写两个方法,分别为doGetAuthorizationInfo(),doGetAuthenticationInfo() ,即授权和认证
ShiroConfig.java
/**
* shiro 的配置类
*/
@Configuration//配置类注解
public class ShiroConfig {
/**
* 创建ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManger){
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//设置安全管理器
shiroFilterFactoryBean.setSecurityManager(securityManger);
/**
* shiro的内置过滤器。可以实现权限相关的拦截器
* 常用的过滤器
* anon:无需认证(登录)可以访问
* authc:必须认证才可以访问
* user:如果使用remeberme的功能可以直接访问
* perms:该资源必须得到资源权限才可以访问
* role:该资源必须得到角色权限才可以访问
*/
Map<String,String> filterMap = new LinkedHashMap<String,String>();
filterMap.put("/add","authc");
filterMap.put("/update","authc");
filterMap.put("/tt","authc");
// filterMap.put("/*","authc");
//对资源进行授权 perms中为自定义字符
filterMap.put("/add","perms[user:add]");
filterMap.put("/add","perms[user:update]");
//修改默认的登录跳转页面
shiroFilterFactoryBean.setLoginUrl("/toLogin");
//修改默认的未授权的跳转页面
shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
return shiroFilterFactoryBean;
}
/**
* 创建DefaultWebSecurityManger
*/
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManger(UserRealm userRealm){
DefaultWebSecurityManager securityManger = new DefaultWebSecurityManager();
//关联realm
securityManger.setRealm(userRealm);
return securityManger;
}
/**
* 创建Realm
*/
@Bean("name=userRealm")//加入到Spring容器中name指定名字
public UserRealm getRealm(){
return new UserRealm();
}
/**
* 配置ShiroDialect,用户thymeleaf和shiro标签的配合使用
*/
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
UserRealm.java
/**
1. 自定义Realm
*/
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
/**
* 执行授权逻辑
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("shouquan");
//给资源进行授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//数据库查询用户授权
Subject subject = SecurityUtils.getSubject();
User user = (User)subject.getPrincipal();//对应认证中的返回对象
//添加资源的授权的字符串
info.addStringPermission(user.getPerms());//拿到数据库的用户授权信息
return info;
}
/**
* 执行认证逻辑
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("renzheng");
//编写Shiro判断逻辑,判断用户名和密码
//1.判断用户名
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
User user = userService.findByName(token.getUsername());
if(user == null){
//用户名不存在
return null;//shiro底层会抛出UnkonwAccountException
}
//2.判断密码
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
配置登录逻辑
UserController.java
- subject.login(token)必然会去调用UserRealm中的认证方法
/**
* 登录逻辑处理
*/
@RequestMapping("/login")
public String login(String name ,String password ,Model model){
/*
* 使用shiro编写认证操作
*/
//1.获取subject
Subject subject = SecurityUtils.getSubject();
//2.封装用户数据
UsernamePasswordToken token = new UsernamePasswordToken(name,password);
//3.执行登录方法
try{
subject.login(token);
//登录成功
//跳转test.html
return "redirect:/success";
}catch (UnknownAccountException e){
model.addAttribute("msg","用户名不存在");
return "/toLogin";
}catch (IncorrectCredentialsException e){
model.addAttribute("msg","密码不正确");
return "/toLogin";
}
}
toLogin.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>页面登录</title>
</head>
<body>
<h3 th:text="${msg}" style="color: red;"></h3>
<form method="post" action="/login">
用户名:<input type="text" name="name"/></br>
密码:<input type="password" name="password"/></br>
<input type="submit" value="登录"/>
</form>
</body>
</html>
配置授权
授权直接去到UserRealm查询权限,页面来先显示已授权的菜单,现在ShiroConfig中配置ShiroDialect,通过shiro:hasPermission=“自定义权限”,来是否显示。
text.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml" xmlns:shiro="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>测试Thymeleaf</title>
</head>
<body>
<div shiro:hasPermission="user:add">
进入用户添加功能:<a href="add">用户添加</a></br>
</div>
<div shiro:hasPermission="user:update">
进入用户添加功能:<a href="update">用户更新</a>
</div>
</body>
</html>