前言
在网上看了一个开源的springboot项目,上面有非常全的springboot结合各种框架的配置,其中就有shiro,于是拿过来研究!
地址:https://github.com/wuyouzhuguli/SpringAll,从11开始看!他的项目里用的是Oracle数据库,如果你是MySQL数据库需要做对应的更换!
maven阿里云镜像下载不了Oracle的依赖,所以你需要自己准备对应jar包install本地!
更换MySQL数据库
一、更换依赖
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
二、更改配置
spring:
datasource:
druid:
# 数据库访问配置, 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&autoReconnect=true&failOverReadOnly=false&zeroDateTimeBehavior=convertToNull
username: root
password: 123456
三、改换建表语句
他的Oracle建表语句并不能在MySQL里面直接用,因为类型都不匹配,不过这个并不是大问题,我这里贴上SQL
CREATE TABLE `t_user` (
`id` int(20) NOT NULL,
`username` varchar(255) DEFAULT NULL,
`passwd` varchar(255) DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
`status` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
上几条数据:
INSERT INTO T_USER VALUES ('2', 'test', '7a38c13ec5e9310aed731de58bbc4214', TO_DATE('2017-11-19 17:20:21', 'YYYY-MM-DD HH24:MI:SS'), '0');
INSERT INTO T_USER VALUES ('1', 'mrbird', '42ee25d1e43e9f57119a00d0a39e5250', TO_DATE('2017-11-19 10:52:48', 'YYYY-MM-DD HH24:MI:SS'), '1');
这里密码是使用MD5盐值加密,代码请看util包下的加密工具,伪造数据这种事我就不详细说了!
Shiro的配置
当然这里我只贴核心代码,其余需要说明的地方请各位仔细看注释
,有任何不懂得都可以留言或者进群交流!
import java.util.LinkedHashMap;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.springboot.shiro.ShiroRealm;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/fonts/**", "anon");
filterChainDefinitionMap.put("/img/**", "anon");
filterChainDefinitionMap.put("/druid/**", "anon");
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/", "anon");
filterChainDefinitionMap.put("/**", "user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
//rememberMeManager添加到管理器里面
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
/**
* @Description: 可见 LifecycleBeanPostProcessor 就是通过上述三个方法对Initializable和
* Destroyable这两个类的init方法和destroy方法进行内部调用来实现bean 的生命周期控制
* @Param:
* @return:
* @Author: 朝花不迟暮
* @Date: 2020/10/26
*/
@Bean(name = "lifecycleBeanPostProcessor")
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
@Bean
public ShiroRealm shiroRealm(){
ShiroRealm shiroRealm = new ShiroRealm();
return shiroRealm;
}
/**
* cookie对象
* @return
*/
public SimpleCookie rememberMeCookie() {
// 设置cookie名称,对应login.html页面的<input type="checkbox" name="rememberMe"/>
SimpleCookie cookie = new SimpleCookie("rememberMe");
// 设置cookie的过期时间,单位为秒,这里为一天
cookie.setMaxAge(86400);
return cookie;
}
/**
* cookie管理对象
* @return
*/
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
// rememberMe cookie加密的密钥
cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
}
其实核心代码并不是很多,我这里也没有给全,像和数据库关联的dao层和业务相关的service层我是直接略过了,因为这并不是我们要说的话题。
控制层的改进
在他的源代码里虽然做了rememberMe
功能,但是并没有在业务逻辑上体现出来,仅仅只是设置了一个cookies,我自己在他的基础上将这个功能实现出来,也不是很难!
@GetMapping("/login")
public String login(HttpServletRequest req) {
Cookie[] cookies = req.getCookies();
boolean rememberMe = false;
for (Cookie cookie : cookies)
{
if(cookie.getName().equals("rememberMe")){
System.out.println(cookie.getName().equals("rememberMe"));
rememberMe = cookie.getName().equals("rememberMe");
break;
}
}
if(rememberMe){
return "redirect:index";
}
System.out.println(rememberMe);
return "login";
}
其思路就是在跳转到登陆页的时候判断cookies里面是否有rememberMe
,如果有说明这个用户之前已经登录过了那么就重定向到首页,反之则跳到登录页!
实际展示
浏览器输入:http://localhost:8080/web/login
输入 用户名:admin
,密码:123456
,点击记住我,这样浏览器上就有你的cookies
只要你不注销,你就可以直接进入首页,即使进入登录页也会重定向到首页!
咨询请找
QQ:707409741
群:118767976
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16424.html