[top]
0.shiro get地址 可以参考案例
https://github.com/apache/shiro/tree/master/samples
个人代码见本地:E:\IdeaWorkSpace\springbootStudy\springbootKuang\springboot-08-shrio
1.shiro 三大对象
Subject 用户
SecurityManager 管理所有用户
Realm 连接数据
2.导入jar包
<dependencies>
<!--thymeleaf-整合-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!--整合mybatis druid连接数据库-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--以上为整合mybatis druid连接数据库-->
<!--shiro整合spring-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
3.自定义realm类
import com.sgc.pojo.User;
import com.sgc.service.UserService;
import org.apache.shiro.SecurityUtils;
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.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
//自定义UserRealm extends AuthorizingRealm
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("执行了授权==》doGetAuthorizationInfo");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//info.addStringPermission("user:add");
//拿到当前登录的对象
Subject subject = SecurityUtils.getSubject();
//拿到use对象
User currentUser = (User) subject.getPrincipal();
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("执行了认证==》doGetAuthenticationInfo");
//这里的token可以与controller中的连用
UsernamePasswordToken userToken = (UsernamePasswordToken)token;
//连接数据库
User user = userService.queryUserByName(userToken.getUsername());
String username= user.getName();
String password= user.getPwd();
if(username==null){
return null; //会自动抛出UnknownAccountException异常
}
Subject currentUser = SecurityUtils.getSubject();
//这个session是shiro中的session
Session session = currentUser.getSession();
session.setAttribute("loginUser",user);
//密码可以加密 md5 md5盐值加密
//密码验证 shiro会自动做
return new SimpleAuthenticationInfo(user,password,"");
}
}
4.编写shiro配置类
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean 顺序3 从realm开始写
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("manager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
//添加shiro内置过滤器
/*
anno 无需认证就可以访问
authc 认证之后才能访问
user 需要配置记住我功能才能访问
perms 拥有对某个资源的权限才能访问
role 拥有某个角色权限才能访问
*/
Map<String, String> map = new LinkedHashMap<>();
/* map.put("/user/add","authc");
map.put("/user/update","authc");*/
// 授权
map.put("/user/add","perms[user:add]");
map.put("/user/update","perms[user:update]");
map.put("/user/*","authc");
bean.setFilterChainDefinitionMap(map);
//设置登录请求
bean.setLoginUrl("/toLogin");
//设置未授权页面
bean.setUnauthorizedUrl("/unauthorized");
return bean;
}
//DefaultWebSecurityManager 顺序2
@Bean(name="manager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getUserRealm") UserRealm userRealm){
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
//关联realm
manager.setRealm(userRealm);
return manager;
}
//创建realm对象 需要自定义类 顺序1
@Bean
public UserRealm getUserRealm(){
return new UserRealm();
}
//整合ShiroDialect: 用来整合shiro和thymeleaf
@Bean
public ShiroDialect getShiroDialect(){
return new ShiroDialect();
}
}
5.controller层
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping({"/","/index"})
public String hello(Model model){
model.addAttribute("msg","hello,shiro");
return "index";
}
@RequestMapping("/user/add")
public String add(Model model){
return "user/add";
}
@RequestMapping("/user/update")
public String update(Model model){
return "user/update";
}
@RequestMapping("/toLogin")
public String toLogin(Model model){
return "toLogin";
}
@RequestMapping("/login")
public String login(String username,String password,Model model){
//获取当前的用户
Subject currentUser = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
currentUser.login(token);//执行登录的方法
return "index";
}catch (UnknownAccountException e) { //用户名不存在
model.addAttribute("msg","用户名不存在");
return "toLogin";
} catch (IncorrectCredentialsException ice) {
model.addAttribute("msg","密码错误");
return "toLogin";
}
}
//未授权
@RequestMapping("/unauthorized")
@ResponseBody
public String unauthorized(){
return "未经授权 无法访问此页面";
}
}
6.前端界面
登录页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录页</title>
</head>
<body>
<p th:text="${msg}" style="color: red"></p>
<form th:action="@{/login}">
用户名:<input name="username" type="text"><br>
密码:<input name="password" type="text"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
首页
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.thymeleaf.org/thymeleaf-extras-shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<div th:if="${session.loginUser}==null">
<a th:href="@{/toLogin}">登录</a>
</div>
<p th:text="${msg}"></p>
<div shiro:hasPermission="user:add">
<a th:href="@{/user/add}">add</a>
</div>
<div shiro:hasPermission="user:update">
<a th:href="@{/user/update}">update</a>
</div>
</body>
</html>