依赖:
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<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.2</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>
页面:
index
<head>
<meta charset="UTF-8">
<title>index</title>
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.5.4/css/layui.css" media="all">
</head>
<body>
<script src="https://www.layuicdn.com/layui-v2.5.4/layui.js"></script>
<div style="margin-top: 100px;margin-left: 45%">
<a class="layui-btn layui-btn-normal layui-btn-radius" th:href="@{/add}">微信</a>
<a class="layui-btn layui-btn-warm layui-btn-radius" th:href="@{/delete}">企鹅</a>
<a class="layui-btn layui-btn-danger layui-btn-radius" th:href="@{/logOut}">退出</a>
</div>
</body>
页面:login
<head>
<meta charset="UTF-8">
<title>login</title>
<link rel="stylesheet" href="https://www.layuicdn.com/layui-v2.5.4/css/layui.css" media="all">
</head>
<body>
<script src="https://www.layuicdn.com/layui-v2.5.4/layui.js"></script>
<div style="margin-top: 100px;margin-left: 35%">
<p style="color: red;">[[${log}]]</p>
<form class="layui-form" th:action="@{/login}" lay-filter="example">
<div class="layui-form-item">
<label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" name="username" lay-verify="required" placeholder="请输入" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">密码</label>
<div class="layui-input-inline">
<input type="password" name="password" lay-verify="required" placeholder="请输入" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="submit" class="layui-btn" value="登陆">
</div>
</div>
</form>
</div>
</body>
其他页面:user/add.html delete.html
整合mybatis 使用druid数据源
yaml配置:
spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/stu?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall,log4j
maxPoolPreparedstatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
mybatis:
type-aliases-package: com.xzb.pojo
mapper-locations: classpath:/mapper/*.xml
实体类:…
mapper接口java及mapper.xml:
java:
@Mapper
@Repository
public interface UserMapper {
User queryUserByName(@Param("name") String name);
}
xml:
<mapper namespace="com.xzb.mapper.UserMapper">
<select id="queryUserByName" parameterType="string" resultType="user">
select *
from stu.user
where username = #{name};
</select>
</mapper>
yaml绑定:
mybatis:
type-aliases-package: com.xzb.pojo
mapper-locations: classpath:/mapper/*.xml
controller
@Controller
public class ShiroController {
@RequestMapping("/add")
public String toAdd(Model model){
model.addAttribute("msg","微信");
return "user/add";
}
@RequestMapping("/delete")
public String toDelete(Model model){
model.addAttribute("msg","QQ");
return "user/delete";
}
@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("log","用户名错误");
return "login";
}catch (IncorrectCredentialsException e){
model.addAttribute("log","密码错误");
return "login";
}
}
@RequestMapping("/unauth")
@ResponseBody
public String unauthorizedPage(){
return "权限不足";
}
@RequestMapping("/logOut")
public String logOut(){
return "index";
}
}
shiro配置
UserRealm.java
public class UserRealm extends AuthorizingRealm {
@Autowired
UserService userService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.err.println("授权执行了");
//获得用户
Subject subject = SecurityUtils.getSubject();
User currentUser = (User) subject.getPrincipal();
//给相应用户授权
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
if (currentUser.getId()<=2){
info.addStringPermission("add");
}else {
info.addStringPermission("delete");
}
return info;//记得返回
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.err.println("认证执行了");
//获取controller中的token数据
UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//从数据库获得用户名,密码
User user = userService.queryUserByName(userToken.getUsername());
//用户名认证
if (user == null){
return null;
}
//密码认证 可定义加密方式 默认简单加密 将user放入等于是方便授权时调用
return new SimpleAuthenticationInfo(user,user.getPassword(),"");
}
}
ShiroConfig.java配置:
@Configuration
public class ShiroConfig {
/**
* Shiro(ApplicationCode)三大核心
* ShiroSubject (the current 'user)
* ShiroSecurityManager (manages all Subjects)
* Pealm (access your security data)
*
*也就是说对于我们而言,最简单的一个 Shiro 应用:
* 应用代码通过 Subject 来进行认证和授权,
* 而Subject又委托给SecurityManager我们需要给Shiro的SecurityManager注入Realm
* 从而让 SecurityManager 能得到合法
* 的用户及其权限进行判断。
*/
//创建ShiroFilterFactoryBean
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("mySecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
//关联DefaultWebSecurityManager
bean.setSecurityManager(defaultWebSecurityManager);
//配置shiro的内置过滤器
/**
* anon:无需认证就可以访间
* authc:必须认证了 才能让问
* user:必须拥有记住我功能才能用
* perms:拥有对菜 个资源的权限才能访间;
* role:拥有某个角色权限才能访问
*/
Map<String, String> filerMap = new LinkedHashMap<>();
//拦截(请求,认证方式)
filerMap.put("/add","authc");
filerMap.put("/delete","authc");
//权限访问控制
filerMap.put("/add","perms[add]");
filerMap.put("/delete","perms[delete]");
//设置注销
filerMap.put("/logOut","logout");
bean.setFilterChainDefinitionMap(filerMap);
//设置登陆页
bean.setLoginUrl("/toLogin");
//设置权限不足页
bean.setUnauthorizedUrl("/unauth");
return bean;
}
//创建DefaultWebSecurityManager
@Bean(name="mySecurityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//关联Pealm
securityManager.setRealm(userRealm);
return securityManager;
}
//创建Pealm
@Bean
public UserRealm userRealm(){
UserRealm userRealm = new UserRealm();
return userRealm;
}
}