<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot+Shiro+Redis共享Session入門(mén)

          共 15443字,需瀏覽 31分鐘

           ·

          2020-12-04 15:48

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          ? 作者?|??蘇先生139

          來(lái)源 |? urlify.cn/V7Jbeu

          66套java從入門(mén)到精通實(shí)戰(zhàn)課程分享

          在單機(jī)版的Springboot+Shiro的基礎(chǔ)上,這次實(shí)現(xiàn)共享Session。這里沒(méi)有自己寫(xiě)RedisManager、SessionDAO。用的 crazycake 寫(xiě)的開(kāi)源插件

          pom.xml

          "1.0"?encoding="UTF-8"?>
          "http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          ????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">
          ????4.0.0

          ????com.example
          ????demo
          ????0.0.1-SNAPSHOT
          ????jar

          ????demo
          ????Demo?project?for?Spring?Boot

          ????
          ????????org.springframework.boot
          ????????spring-boot-starter-parent
          ????????2.0.3.RELEASE
          ?????????
          ????


          ????
          ????????UTF-8
          ????????UTF-8
          ????????1.8
          ????


          ????
          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-starter-data-redis
          ????????

          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-starter-thymeleaf
          ????????

          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-starter-web
          ????????

          ????????
          ????????
          ????????????org.apache.shiro
          ????????????shiro-all
          ????????????1.3.2
          ????????

          ????????
          ????????
          ????????????com.alibaba
          ????????????fastjson
          ????????????1.2.47
          ????????

          ????????
          ????????
          ????????????org.crazycake
          ????????????shiro-redis
          ????????????3.1.0
          ????????


          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-devtools
          ????????????runtime
          ????????

          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-starter-test
          ????????????test
          ????????

          ????


          ????
          ????????
          ????????????
          ????????????????org.springframework.boot
          ????????????????spring-boot-maven-plugin
          ????????????

          ????????????
          ????????????????org.apache.maven.plugins
          ????????????????maven-compiler-plugin
          ????????????????3.7.0
          ????????????????
          ????????????????????<source>1.8source>
          ????????????????????1.8
          ????????????????

          ????????????

          ????????

          ????




          redis配置文件? ?

          package?com.example.demo.conf;

          import?org.springframework.beans.factory.annotation.Value;
          import?org.springframework.context.annotation.Configuration;
          import?org.springframework.context.annotation.PropertySource;


          @Configuration
          @PropertySource("classpath:conf/redis.properties")
          public?class?RedisConfig?{

          ????@Value("${shiro.redis.host}")
          ????private?String?host;

          ????@Value("${shiro.redis.timeout}")
          ????private?int?timeout;

          ????public?String?getHost()?{
          ????????return?host;
          ????}

          ????public?void?setHost(String?host)?{
          ????????this.host?=?host;
          ????}

          ????public?int?getTimeout()?{
          ????????return?timeout;
          ????}

          ????public?void?setTimeout(int?timeout)?{
          ????????this.timeout?=?timeout;
          ????}
          }

          Shiro配置文件

          package?com.example.demo.conf;

          import?com.example.demo.auth.PermissionRealm;
          import?com.example.demo.common.entity.User;
          import?org.apache.shiro.authc.credential.HashedCredentialsMatcher;
          import?org.apache.shiro.realm.AuthorizingRealm;
          import?org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator;
          import?org.apache.shiro.spring.LifecycleBeanPostProcessor;
          import?org.apache.shiro.spring.web.ShiroFilterFactoryBean;
          import?org.apache.shiro.web.mgt.DefaultWebSecurityManager;
          import?org.apache.shiro.web.servlet.SimpleCookie;
          import?org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
          import?org.crazycake.shiro.RedisCacheManager;
          import?org.crazycake.shiro.RedisManager;
          import?org.crazycake.shiro.RedisSessionDAO;
          import?org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
          import?org.springframework.context.annotation.Bean;
          import?org.springframework.context.annotation.Configuration;
          import?org.springframework.context.annotation.DependsOn;
          import?org.springframework.data.redis.connection.RedisConnectionFactory;
          import?org.springframework.data.redis.core.RedisTemplate;
          import?org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
          import?org.springframework.data.redis.serializer.StringRedisSerializer;

          import?java.util.LinkedHashMap;

          @Configuration
          public?class?ShiroConfig?{

          ????@Bean
          ????public?RedisConfig?redisConfig(){
          ????????return?new?RedisConfig();
          ????}

          ????@Bean
          ????public?RedisManager?redisManager(){
          ????????RedisManager?redisManager?=?new?RedisManager();?????//?crazycake?實(shí)現(xiàn)
          ????????redisManager.setHost(redisConfig().getHost());
          ????????redisManager.setTimeout(redisConfig().getTimeout());
          ????????return?redisManager;
          ????}

          ????@Bean
          ????public?JavaUuidSessionIdGenerator?sessionIdGenerator(){
          ????????return?new?JavaUuidSessionIdGenerator();
          ????}

          ????@Bean
          ????public?RedisSessionDAO?sessionDAO(){
          ????????RedisSessionDAO?sessionDAO?=?new?RedisSessionDAO();?//?crazycake?實(shí)現(xiàn)
          ????????sessionDAO.setRedisManager(redisManager());
          ????????sessionDAO.setSessionIdGenerator(sessionIdGenerator());?//??Session?ID?生成器
          ????????return?sessionDAO;
          ????}

          ????@Bean
          ????public?SimpleCookie?cookie(){
          ????????SimpleCookie?cookie?=?new?SimpleCookie("SHAREJSESSIONID");?//??cookie的name,對(duì)應(yīng)的默認(rèn)是?JSESSIONID
          ????????cookie.setHttpOnly(true);
          ????????cookie.setPath("/");????????//??path為?/?用于多個(gè)系統(tǒng)共享JSESSIONID
          ????????return?cookie;
          ????}

          ????@Bean
          ????public?DefaultWebSessionManager?sessionManager(){
          ????????DefaultWebSessionManager?sessionManager?=?new?DefaultWebSessionManager();
          ????????sessionManager.setGlobalSessionTimeout(redisConfig().getTimeout());????//?設(shè)置session超時(shí)
          ????????sessionManager.setDeleteInvalidSessions(true);??????//?刪除無(wú)效session
          ????????sessionManager.setSessionIdCookie(cookie());????????????//?設(shè)置JSESSIONID
          ????????sessionManager.setSessionDAO(sessionDAO());?????????//?設(shè)置sessionDAO
          ????????return?sessionManager;
          ????}

          ????/**
          ?????*?1.?配置SecurityManager
          ?????*?@return
          ?????*/
          ????@Bean
          ????public?DefaultWebSecurityManager?securityManager(){
          ????????DefaultWebSecurityManager?securityManager?=?new?DefaultWebSecurityManager();
          ????????securityManager.setRealm(realm());??//?設(shè)置realm
          ????????securityManager.setSessionManager(sessionManager());????//?設(shè)置sessionManager
          //????????securityManager.setCacheManager(redisCacheManager());?//?配置緩存的話,退出登錄的時(shí)候crazycake會(huì)報(bào)錯(cuò),要求放在session里面的實(shí)體類(lèi)必須有個(gè)id標(biāo)識(shí)
          ????????return?securityManager;
          ????}

          ????/**
          ?????*?2.?配置緩存
          ?????*?@return
          ?????*/
          //????@Bean
          //????public?CacheManager?cacheManager(){
          //????????EhCacheManager?ehCacheManager?=?new?EhCacheManager();
          //????????ehCacheManager.setCacheManagerConfigFile("classpath:ehcache.xml");
          //????????return?ehCacheManager;
          //????}

          ????@Bean
          ????public?RedisCacheManager?redisCacheManager(){
          ????????RedisCacheManager?cacheManager?=?new?RedisCacheManager();???//?crazycake?實(shí)現(xiàn)
          ????????cacheManager.setRedisManager(redisManager());
          ????????return?cacheManager;
          ????}

          ????/**
          ?????*?3.?配置Realm
          ?????*?@return
          ?????*/
          ????@Bean
          ????public?AuthorizingRealm?realm(){
          ????????PermissionRealm?realm?=?new?PermissionRealm();
          ????????HashedCredentialsMatcher?matcher?=?new?HashedCredentialsMatcher();
          ????????//?指定加密算法
          ????????matcher.setHashAlgorithmName("MD5");
          ????????//?指定加密次數(shù)
          ????????matcher.setHashIterations(10);
          ????????//?指定這個(gè)就不會(huì)報(bào)錯(cuò)
          ????????matcher.setStoredCredentialsHexEncoded(true);
          ????????realm.setCredentialsMatcher(matcher);
          ????????return?realm;
          ????}

          ????/**
          ?????*?4.?配置LifecycleBeanPostProcessor,可以來(lái)自動(dòng)的調(diào)用配置在Spring?IOC容器中?Shiro?Bean?的生命周期方法
          ?????*?@return
          ?????*/
          ????@Bean
          ????public?LifecycleBeanPostProcessor?lifecycleBeanPostProcessor(){
          ????????return?new?LifecycleBeanPostProcessor();
          ????}

          ????/**
          ?????*?5.?啟用IOC容器中使用Shiro的注解,但是必須配置第四步才可以使用
          ?????*?@return
          ?????*/
          ????@Bean
          ????@DependsOn("lifecycleBeanPostProcessor")
          ????public?DefaultAdvisorAutoProxyCreator?defaultAdvisorAutoProxyCreator(){
          ????????return?new?DefaultAdvisorAutoProxyCreator();
          ????}

          ????/**
          ?????*?6.?配置ShiroFilter
          ?????*?@return
          ?????*/
          ????@Bean
          ????public?ShiroFilterFactoryBean?shiroFilterFactoryBean(){
          ????????LinkedHashMap?map?=?new?LinkedHashMap<>();
          ????????//?靜態(tài)資源
          ????????map.put("/css/**",?"anon");
          ????????map.put("/js/**",?"anon");

          ????????//?公共路徑
          ????????map.put("/login",?"anon");
          ????????map.put("/register",?"anon");
          ????????//map.put("/*",?"anon");

          ????????//?登出,項(xiàng)目中沒(méi)有/logout路徑,因?yàn)閟hiro是過(guò)濾器,而SpringMVC是Servlet,Shiro會(huì)先執(zhí)行
          ????????map.put("/logout",?"logout");

          ????????//?授權(quán)
          ????????map.put("/user/**",?"authc,roles[user]");
          ????????map.put("/admin/**",?"authc,roles[admin]");

          ????????//?everything?else?requires?authentication:
          ????????map.put("/**",?"authc");

          ????????ShiroFilterFactoryBean?factoryBean?=?new?ShiroFilterFactoryBean();
          ????????//?配置SecurityManager
          ????????factoryBean.setSecurityManager(securityManager());
          ????????//?配置權(quán)限路徑
          ????????factoryBean.setFilterChainDefinitionMap(map);
          ????????//?配置登錄url
          ????????factoryBean.setLoginUrl("/");
          ????????//?配置無(wú)權(quán)限路徑
          ????????factoryBean.setUnauthorizedUrl("/unauthorized");
          ????????return?factoryBean;
          ????}

          ????/**
          ?????*?配置RedisTemplate,充當(dāng)數(shù)據(jù)庫(kù)服務(wù)
          ?????*?@return
          ?????*/
          ????@Bean
          ????public?RedisTemplate?redisTemplate(RedisConnectionFactory?connectionFactory){
          ????????RedisTemplate?redisTemplate?=?new?RedisTemplate<>();
          ????????redisTemplate.setConnectionFactory(connectionFactory);
          ????????redisTemplate.setKeySerializer(new?StringRedisSerializer());
          ????????redisTemplate.setValueSerializer(new?Jackson2JsonRedisSerializer(User.class));
          ????????return?redisTemplate;
          ????}

          }

          UserService

          package?com.example.demo.service;

          import?com.example.demo.common.entity.User;

          import?java.util.List;


          public?interface?UserService?{

          ????void?addUser(User?user);

          ????User?login(User?user);

          ????List?getUsers();

          }

          impl

          package?com.example.demo.service.impl;

          import?com.example.demo.common.PasswordUtils;
          import?com.example.demo.common.entity.User;
          import?com.example.demo.service.UserService;
          import?org.springframework.beans.factory.annotation.Autowired;
          import?org.springframework.data.redis.core.RedisTemplate;
          import?org.springframework.stereotype.Service;

          import?java.util.ArrayList;
          import?java.util.List;

          @Service
          public?class?UserServiceImpl?implements?UserService?{

          ????@Autowired
          ????private?RedisTemplate?redisTemplate;

          ????@Override
          ????public?void?addUser(User?user)?{
          ????????user.setPassword(PasswordUtils.saltAndMd5(user.getUsername(),user.getPassword()));??//?加密
          ????????redisTemplate.boundHashOps("users").put(user.getUsername(),?user);
          ????}

          ????@Override
          ????public?User?login(User?user)?{
          ????????user.setPassword(PasswordUtils.saltAndMd5(user.getUsername(),user.getPassword()));??//?加密
          ????????User?u?=?(User)?redisTemplate.boundHashOps("users").get(user.getUsername());
          ????????if?(u?==?null?||?!check(user,?u)){
          ????????????return?null;
          ????????}
          ????????return?u;
          ????}

          ????@Override
          ????public?List?getUsers()?{
          ????????List?list?=?redisTemplate.boundHashOps("users").values();
          ????????List?users?=?new?ArrayList<>();
          ????????list.forEach(u->{
          ????????????users.add((User)?u);
          ????????});
          ????????return?users;
          ????}

          ????private?boolean?check(User?a,?User?b){
          ????????if?(a.getUsername().equals(b.getUsername())?&&?a.getPassword().equals(b.getPassword())){
          ????????????return?true;
          ????????}
          ????????return?false;
          ????}
          }

          controller

          package?com.example.demo.controller;

          import?com.example.demo.common.entity.User;
          import?com.example.demo.common.response.BaseResponse;
          import?com.example.demo.service.UserService;
          import?org.apache.shiro.SecurityUtils;
          import?org.apache.shiro.authc.UsernamePasswordToken;
          import?org.apache.shiro.subject.Subject;
          import?org.springframework.beans.factory.annotation.Autowired;
          import?org.springframework.web.bind.annotation.RequestBody;
          import?org.springframework.web.bind.annotation.RequestMapping;
          import?org.springframework.web.bind.annotation.RestController;
          import?org.springframework.web.servlet.ModelAndView;


          @RestController
          public?class?SimpleController?{

          ????@Autowired
          ????private?UserService?userService;

          ????@RequestMapping("/")
          ????public?ModelAndView?index(){
          ????????return?new?ModelAndView("index");
          ????}

          ????@RequestMapping("/login")
          ????public?BaseResponse?login(@RequestBody?User?user){
          ????????BaseResponse?response?=?new?BaseResponse<>(0,"登陸成功");
          ????????Subject?subject?=?SecurityUtils.getSubject();
          ????????UsernamePasswordToken?token?=?new?UsernamePasswordToken(
          ????????????????user.getUsername(),?user.getPassword());
          ????????subject.login(token);
          ????????response.setData("/home");
          ????????return?response;
          ????}

          ????@RequestMapping("/register")
          ????public?BaseResponse?register(@RequestBody?User?user){
          ????????userService.addUser(user);
          ????????return?new?BaseResponse(0,"注冊(cè)成功");
          ????}

          ????@RequestMapping("/home")
          ????public?ModelAndView?home(){
          ????????ModelAndView?mv?=?new?ModelAndView("home");
          ????????mv.addObject("users",?userService.getUsers());
          ????????return?mv;
          ????}
          }

          redis.properties

          shiro.redis.host=localhost:6379
          shiro.redis.timeout=1800000

          applicatin.properties

          #server.port=8080
          server.port=8081
          #server.port=8082

          spring.redis.host=127.0.0.1
          spring.redis.port=6379

          index.html


          "en"?xmlns:th="http://www.thymeleaf.org">

          ????"UTF-8">
          ????Index
          ????"@{css/index.css}"?rel="stylesheet"?type="text/css">


          ????"container">
          ????????"header">
          ????????????

          初級(jí)SpringBoot+Shiro小栗子?Node-One


          ????????????
          ????????
          ????????"main">
          ????????????"left">
          ????????????????"form-group">
          ????????????????????type="text"?name="username"?placeholder="請(qǐng)輸入用戶名">
          ????????????????
          ????????????????"form-group">
          ????????????????????type="password"?name="password"?placeholder="請(qǐng)輸入密碼">
          ????????????????
          ????????????????"form-group">
          ????????????????????"javascript:;"?id="login">登錄
          ????????????????
          ????????????????"form-group">
          ????????????????????"/home">點(diǎn)我!不登錄進(jìn)不去
          ????????????????
          ????????????
          ????????????"right">
          ????????????????"form-group">
          ????????????????????type="text"?name="username"?placeholder="請(qǐng)輸入用戶名">
          ????????????????
          ????????????????"form-group">
          ????????????????????type="password"?name="password"?placeholder="請(qǐng)輸入密碼">
          ????????????????
          ????????????????"form-group">
          ????????????????????type="text"?name="show"?placeholder="自我介紹">
          ????????????????
          ????????????????"form-group">
          ????????????????????"javascript:;"?id="register">注冊(cè)
          ????????????????
          ????????????
          ????????
          ????
          ????
          ????????
          ????




          home.html


          "en"?xmlns:th="http://www.thymeleaf.org">

          ????"UTF-8">
          ????Home
          ????"@{css/index.css}"?rel="stylesheet"?type="text/css">


          "container">
          ????"header">
          ????????

          初級(jí)SpringBoot+Shiro小栗子?Node-One


          ????????
          ????????"/logout">退出登錄
          ????
          ????"main">
          ????????"table">
          ????????????
          ????????????
          ????????????????Username
          ????????????????Password
          ????????????????Show
          ????????????
          ????????????
          ????????????
          ????????????"u?:?${users}">
          ????????????????[[${u.username}]]
          ????????????????[[${u.password}]]
          ????????????????[[${u.show}]]
          ????????????
          ????????????
          ????????
          ????



          以上兩種配置各打包一次(記得留著打包好的jar包)

          http://nginx.org/

          解壓到無(wú)中文目錄,修改Nginx配置文件

          upstream?myapp{
          ????????server?127.0.0.1:8081?weight=1;
          ????????server?127.0.0.1:8082?weight=1;
          ????}

          ????server{
          ????????????listen???????80;
          ????????????server_name??myapp;

          ????????????location?/?{
          ????????????????proxy_pass?http://myapp;
          ????????????????proxy_set_header???Host?????????????$host;
          ????????????????proxy_set_header???X-Real-IP????????$remote_addr;
          ????????????????proxy_set_header???X-Forwarded-For??$proxy_add_x_forwarded_for;
          ????????????}
          ????}

          到此,先啟動(dòng)兩個(gè)jar包(分別是8081,Node-One;8082,Node-Two)

          然后啟動(dòng)Nginx

          瀏覽器訪問(wèn):http://localhost/

          ?

          ?刷新看看..

          ?


          ?隨便在一個(gè)節(jié)點(diǎn)上注冊(cè),登錄,然后刷新到另外一個(gè)節(jié)點(diǎn),發(fā)現(xiàn)不用登錄就可以訪問(wèn)權(quán)限資源

          ?


          ?

          ?

          ?GitHub

          https://github.com/Mysakura/boot-shiro-session

          package?com.example.demo.controller;

          import?com.example.demo.common.entity.User;
          import?com.example.demo.common.response.BaseResponse;
          import?com.example.demo.service.UserService;
          import?org.apache.shiro.SecurityUtils;
          import?org.apache.shiro.authc.UsernamePasswordToken;
          import?org.apache.shiro.subject.Subject;
          import?org.springframework.beans.factory.annotation.Autowired;
          import?org.springframework.web.bind.annotation.RequestBody;
          import?org.springframework.web.bind.annotation.RequestMapping;
          import?org.springframework.web.bind.annotation.RestController;
          import?org.springframework.web.servlet.ModelAndView;


          @RestController
          public?class?SimpleController?{

          ????@Autowired
          ????private?UserService?userService;

          ????@RequestMapping("/")
          ????public?ModelAndView?index(){
          ????????return?new?ModelAndView("index");
          ????}

          ????@RequestMapping("/login")
          ????public?BaseResponse?login(@RequestBody?User?user){
          ????????BaseResponse?response?=?new?BaseResponse<>(0,"登陸成功");
          ????????Subject?subject?=?SecurityUtils.getSubject();
          ????????UsernamePasswordToken?token?=?new?UsernamePasswordToken(
          ????????????????user.getUsername(),?user.getPassword());
          ????????subject.login(token);
          ????????response.setData("/home");
          ????????return?response;
          ????}

          ????@RequestMapping("/register")
          ????public?BaseResponse?register(@RequestBody?User?user){
          ????????userService.addUser(user);
          ????????return?new?BaseResponse(0,"注冊(cè)成功");
          ????}

          ????@RequestMapping("/home")
          ????public?ModelAndView?home(){
          ????????ModelAndView?mv?=?new?ModelAndView("home");
          ????????mv.addObject("users",?userService.getUsers());
          ????????return?mv;
          ????}
          }






          粉絲福利:實(shí)戰(zhàn)springboot+CAS單點(diǎn)登錄系統(tǒng)視頻教程免費(fèi)領(lǐng)取

          ???

          ?長(zhǎng)按上方微信二維碼?2 秒
          即可獲取資料



          感謝點(diǎn)贊支持下哈?


          瀏覽 27
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    黄色小视频在线免费看 | 激情乱伦中文字幕 | 99色99| 天天摸天天操 | 国产第一精品色 |