测试环境搭建实现拦截
<!-- shiro整合包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.6.0</version>
</dependency>
配置Shiro
@Configuration
public class ShiroConfig {
//Shiro三大核心
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean= new ShiroFilterFactoryBean();
//设置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
// 添加shiro的内置过滤器
// anon 无需认证就可以访问
// authc 认证才可以访问
// user 记住我功能
// perms 拥有对某个资源的权限才可以访问
// role拥有某哥角色才可以访问
Map<String,String> filterMap=new LinkedHashMap<>();
filterMap.put("/user/add","authc");//增加一个访问限制
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
//创建realm对象 ,自定义 1
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//ShiroFilterFactoryBean
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
重写认证和授权两个方法
public class UserRealm extends AuthorizingRealm {
@Override
//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证");
return null;
}
我们发现当进入没有权限的界面时会走一个login,所以我们得写一个login
<h2>自定义登录</h2>
<p>账号:<input required type="text" name="username"></p>
<p>密码:<input required type="password" name="password"></p>
<input type="submit" value="登录">
- Configuration配置
bean.setLoginUrl("/toLogin");//跳转到登录界面
- Controller
@RequestMapping("/toLogin")
public String toLogin(){
return "login";
}
实现用户认证
- 首先我们先写一个表单提交的Controller
@RequestMapping("/login")
public String login(String username,String password,Model model){
//获取当前的用户
Subject subject = SecurityUtils.getSubject();
//封装用户的登录数据
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);//执行登录方法,没有异常就说明登录oko
return "index";
}catch (UnknownAccountException e){//账号错误
model.addAttribute("msg","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){//密码错误
model.addAttribute("msg","密码错误");
return "login";
}
}
- 在认证中判断
System.out.println("认证");
// 获取当前的用户账号密码
String username="admin";
String password="123456";
//转换成封装着用户信息的token
UsernamePasswordToken user= (UsernamePasswordToken) authenticationToken;
if (!user.getUsername().equals(username)){
return null;//null说明没有抛出异常
}
//密码认证 shiro自动判别
return new SimpleAuthenticationInfo("",password,"");
}
- 演示
整合mybatis实现从数据库中查找
- 环境整合
</dependency>
<!-- druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!-- 日志-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<!-- mysql 相关-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
换成从数据库中读取数据
System.out.println("认证");
// 获取当前的用户账号密码
//连接真实数据库
//转换成封装着用户信息的token
UsernamePasswordToken user= (UsernamePasswordToken) authenticationToken;
User RealUser = userService.queryUserByName(user.getUsername());
if (RealUser==null){
return null;
}
//如果数据库中有这个人直接获取这个人的密码然后和前端进行比对
return new SimpleAuthenticationInfo("",RealUser.getPassword(),"");
}
请求授权实现
从数据库中获取身份
相关代码
@Configuration
public class ShiroConfig {
//Shiro三大核心
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
// 设置安全管理器
// 添加shiro的内置过滤器
// anon 无需认证就可以访问
// authc 认证才可以访问
// user 记住我功能
// perms 拥有对某个资源的权限才可以访问
// role拥有某哥角色才可以访问
ShiroFilterFactoryBean bean= new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
Map<String,String> filterMap=new LinkedHashMap<>();
//授权操作 perms 身份满足才可以进相应的界面
filterMap.put("/user/add","perms[user:add]");//
filterMap.put("/user/update","perms[user:update]");
filterMap.put("/user/*","authc");//增加一个访问限制访问add时需要进行登录认证
bean.setFilterChainDefinitionMap(filterMap);
bean.setLoginUrl("/toLogin");//跳转到登录界面
//未授权的请求
bean.setUnauthorizedUrl("/noauth");
return bean;
}
//创建realm对象 ,自定义 1
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
//ShiroFilterFactoryBean
@Bean
public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联realm
securityManager.setRealm(userRealm);
return securityManager;
}
授权于认证方法
public class UserRealm extends AuthorizingRealm {
@Autowired
UserServiceImpl userService;
@Override
//授权
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 将授权写死
// info.addStringPermission("user:add");
// 从数据库中获取身份
Subject subject = SecurityUtils.getSubject();
User CurrentUser = (User) subject.getPrincipal();
//设置当前用户权限
info.addStringPermission(CurrentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("认证");
// 获取当前的用户账号密码
//连接真实数据库
//转换成封装着用户信息的token
UsernamePasswordToken user= (UsernamePasswordToken) authenticationToken;
User RealUser = userService.queryUserByName(user.getUsername());
if (RealUser==null){
return null;
}
//如果数据库中有这个人直接获取这个人的密码然后和前端进行比对
return new SimpleAuthenticationInfo(RealUser,RealUser.getPassword(),"");
}
}
注销
整合Thyme leaf
<!--shiro-thymeleaf整合-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
- 完成配置
@Bean
public ShiroDialect shiroDialect(){
return new ShiroDialect();
}
- 导入命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
- 保存session在认证中
// 将查询的用户放到session中
Subject CurrentSubject = SecurityUtils.getSubject();
Session session = CurrentSubject.getSession();
session.setAttribute("user",RealUser);