SpringBoot框架
Shiro的框架
MyBatis框架
Spring框架
thymeleaf技术
SSM三层框架
数据库
Subject——org.apache.shiro.subject.Subject
特定于当前与软件交互的实体的安全视图
SecurityManager——org.apache.shiro.mgt.SecurityManager
Shiro架构的核心,管理并协调各个组件共同完成安全工作,它还管理每个应用程序用户的Shiro视图,因此它知道如何为每个用户执行安全操作。
Authenticator——org.apache.shiro.authc.Authenticator
Authenticator是负责认证的组件,当用户尝试登录时,登录是由Authenticator来执行的,Authenticator将会从Realms取出用户信息,来和用户提供的登录信息进行比对
Authenticator Strategy——org.apache.shiro.authc.pam.AuthenticationStrategy
如果超过一个Realm被配置了,这个AuthenticationStrategy将会协调这些Realms来决定认证操作是否成功,比如,认证成功是需要所有的Realms都认证成功,还是仅仅一个Realm成功
Authorizer——org.apache.shiro.authz.Authorizer
Authorizer是负责访问控制的组件,换句话说,它负责检测用户是否有执行某个操作的权限。和Authenticator一样,Authorizer也从多个Realms数据源中获取用户的角色信息和权限信息,通过这些信息来判断用户是否可以执行某个操作
SessionManager——org.apache.shiro.session.mgt.SessionManager
注意不是SecurityManager,SessionManager负责创建和管理用户的Session周期。在安全框架中,Shiro提供了一个独有的特性,Shiro可以在任何环境中管理用户会话,即使实在非Web/Servlet和非EJB容器环境中,默认情况下,Shiro将会使用已有的会话机制,如Servlet容器,如果没有,Shiro将会使用内建的企业会话管理机制来管理会话。通过SessionDao,我们可以使用任何数据源来持久化Session
SessionDAO——org.apache.shiro.session.mgt.eis.SessionDAO
SessionDAO代表SessionManager执行会话持久性(CRUD)操作。它允许将任何数据存储插入到Session Management基础结构中
CacheManager——org.apache.shiro.cache.CacheManager
CacheManager负责创建Shiro中的其他组件的Cache实例并管理其生命周期,因为Shiro需要访问各种数据源来进行认证,授权和会话管理,缓存一直是框架中的一流架构特性,可以在使用这些数据源时提高性能,任何现代的开源或者企业缓存产品都可以接入Shiro中
Cryptography——org.apache.shiro.crypto.*
Shiro的crypto包包含了易于使用和理解的常见加密算法实现。使用过Java自带的加密库的人都应该知道它很难使用,Shiro提供的加密API简化了复杂的Java机制,让加密更便于使用
Realms——org.apache.shiro.realm.Realm
正如前面提到的,Realms是Shiro和应用程序数据的桥梁,当需要执行认证和授权时,Shiro会从至少一个Realm中寻找用户信息,应用程序中可以配置许多个Realm,Shiro会在必要时协调这些Realm
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.7.4
com.lop
shiro-springboot
0.0.1-SNAPSHOT
shiro-springboot
Demo project for Spring Boot
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.2
org.thymeleaf.extras
thymeleaf-extras-shiro
2.0.0
com.alibaba
druid
1.2.12
log4j
log4j
1.2.14
mysql
mysql-connector-java
1.2.17
org.apache.shiro
shiro-spring
1.9.1
org.thymeleaf
thymeleaf-spring5
org.thymeleaf.extras
thymeleaf-extras-java8time
3.0.4.RELEASE
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.xmlunit
xmlunit-core
2.5.1
compile
org.springframework.boot
spring-boot-maven-plugin
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initial-size: 5
min-idle: 5
max-active: 20
# 配置获取连接等待超时的时间
max-wait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
# 打开PSCache,并且指定每个连接上PSCache的大小
pool-prepared-statements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 最好的功能
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall
use-global-data-source-stat: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
Document
假如hasPermisssion有这个限制
add
Title
登录
package com.lop.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface UserMapper {
public UserMapper queryUserByName(String username);
}
package com.lop.Service;
import com.lop.pojo.User;
public interface UserService {
public User queryUserByName(String username);
}
package com.lop.Service;
import com.lop.mapper.UserMapper;
import com.lop.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceLmp implements UserService {
@Autowired
UserMapper userMapper;
@Override
public User queryUserByName(String username) {
userMapper.queryUserByName(username);
return null;
}
}
package com.lop.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.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 首页控制器
*/
@Controller
public class MyController {
@RequestMapping({"/", "/index"})
public String toIndex(Model model) {
model.addAttribute("msg", "hllow");
return "index";
}
@RequestMapping("user/add")
public String add() {
return "user/add";
}
@RequestMapping("user/update")
public String update() {
return "user/update";
}
@RequestMapping("/tologin")
public String toLogin() {
return "login";
}
@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);
return "index";
} catch (UnknownAccountException e) {
model.addAttribute("msg", "用户的名字步存在");
return "login";
} catch (IncorrectCredentialsException e) {
model.addAttribute("msg", "用户的密码有误");
return "login";
}
}
@RequestMapping("/noauth")
public String unauthorized(){
return "没有授权无法访问信息";
}
}
认证授权
package com.lop.config;
import com.lop.Service.UserService;
import com.lop.pojo.User;
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
*/
public class UserRealm extends AuthorizingRealm {
//把用户数据库拿过来 连接真实数据库
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("----------------------授权");
// SimpleAuthorizationInfo
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//打开没有授权的功能
info.addStringPermission("uder:add");
//拿到当前对象
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();//拿到user对象
//设置当前用户的权限
info.addStringPermission(currentUser.getPerms());
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("==========================认证");
// String name = "root";
// String password = "123456";
UsernamePasswordToken usertoken = (UsernamePasswordToken) token;
//连接真实数据库
User user=userService.queryUserByName(usertoken.getUsername());
if (user == null) {
return null;
}
Subject cursubject = SecurityUtils.getSubject();
Session session = cursubject.getSession();
session.setAttribute("loginUser",user);
// if(!usertoken.getUsername().equals(name)){
// return null;
// }
//密码认证
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
package com.lop.config;
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.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
//授权的信息内容 有user:add 没有授权
filterMap.put("/user/add", "perms[user:add]");
filterMap.put("/user/update", "perms[user:update]");
//用户没有授权请前往这个页面
bean.setLoginUrl("/noauth");
//设置登录请求
bean.setLoginUrl("/tologin");
bean.setFilterChainDefinitionMap(filterMap);
return bean;
}
// 自定义的UserRealm
// @Bean(name = "userRealm")
@Bean
public UserRealm userRealm() {
return new UserRealm();
}
假如hasPermisssion有这个限制
add