最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

教你使用springSecurity+jwt實(shí)現(xiàn)互踢功能

 更新時(shí)間:2021年11月24日 11:57:54   作者:txSong123  
JWT作為一個(gè)開(kāi)放的標(biāo)準(zhǔn)( RFC 7519 ),定義了一種簡(jiǎn)潔的,自包含的方法用于通信雙方之間以Json對(duì)象的形式安全的傳遞信息。接下來(lái)通過(guò)本文給大家介紹springSecurity+jwt實(shí)現(xiàn)互踢功能,需要的朋友可以參考下

jwt介紹:

? ? ? ? JWT是一種用于雙方之間傳遞安全信息的簡(jiǎn)潔的、URL安全的表述性聲明規(guī)范。JWT作為一個(gè)開(kāi)放的標(biāo)準(zhǔn)( RFC 7519 ),定義了一種簡(jiǎn)潔的,自包含的方法用于通信雙方之間以Json對(duì)象的形式安全的傳遞信息。

jwt認(rèn)證流程介紹:

1. 用戶使用賬號(hào)和面發(fā)出post請(qǐng)求;?

2. 服務(wù)器使用私鑰創(chuàng)建一個(gè)jwt;?

3. 服務(wù)器返回這個(gè)jwt給瀏覽器;?

4. 瀏覽器將該jwt串在請(qǐng)求頭中像服務(wù)器發(fā)送請(qǐng)求;?

5. 服務(wù)器驗(yàn)證該jwt;?

6. 返回響應(yīng)的資源給瀏覽器。

一.思路:

原來(lái)的實(shí)現(xiàn)用戶登錄態(tài)是:
1.后臺(tái)登陸成功后生成一個(gè)令牌(uuid)----JwtAuthenticationSuccessHandler
2.后臺(tái)把它包裝成jwt數(shù)據(jù),然后返回給前端—JwtAuthenticationSuccessHandler
3.后臺(tái)把它加入redis緩存中,并設(shè)置失效時(shí)間----JwtAuthenticationSuccessHandler
4.前端調(diào)用接口時(shí),帶入jwt
5.后臺(tái)寫(xiě)個(gè)攔截器或者過(guò)濾器,在前端調(diào)用接口的時(shí)候,從request的header中獲取jwt,在緩存中搜索,如果存在則處于登錄態(tài),并重置失效時(shí)間(這樣用戶在有效時(shí)間內(nèi)就處于登錄態(tài))—JwtSecurityContextRepository
6.解釋下:springSecurity是個(gè)過(guò)濾器璉,是由一個(gè)一個(gè)的過(guò)濾器組成的

現(xiàn)在的互踢:
1.后臺(tái)在登陸成功后,用用戶id組成一個(gè)key,查詢r(jià)edis緩存中的value
2.和新的jwt比較,如果不一樣則把查到的jwt當(dāng)做key從redis中刪掉,就是上面第三步存儲(chǔ)的
3.把用戶id組成一個(gè)key,把上面jwt當(dāng)做value傳入緩存中
4.在上面的第5步,也重置下我們這里存儲(chǔ)的值

*上面 指的是原來(lái)的實(shí)現(xiàn)用戶登錄態(tài)

package com.lc.gansu.security.component.jwt;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lc.gansu.framework.core.ConstantOfReturnCode;
import com.lc.gansu.framework.core.RedisKey;
import com.lc.gansu.framework.core.ReturnObject;
import com.lc.gansu.security.component.SecurityConstants;
import com.lc.gansu.security.domain.User;
import com.lc.gansu.security.utility.JWTHS256;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    //private final RequestCache requestCache = new HttpSessionRequestCache();
    private final ObjectMapper jacksonObjectMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    public JwtAuthenticationSuccessHandler(ObjectMapper jacksonObjectMapper, RedisTemplate<String, Object> redisTemplate) {
        this.jacksonObjectMapper = jacksonObjectMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        log.info("JwtAuthenticationSuccessHandler=success");
        clearAuthenticationAttributes(request);
        handle(response, authentication);
    }

    protected final void clearAuthenticationAttributes(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session == null) return;
        session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
    }

    protected void handle(HttpServletResponse response, Authentication authentication) throws IOException {
        if (response.isCommitted()) {
            log.debug("Response has already been committed.");
            return;
        }
        User sysUser = (User) authentication.getPrincipal();
        sysUser.setClazz(authentication.getClass());
        //AuthenticationAdapter authenticationAdapter=AuthenticationAdapter.authentication2AuthenticationAdapter(authentication);
        String authOfjson = jacksonObjectMapper.writeValueAsString(sysUser);
        String subject = UUID.randomUUID().toString();
        String authOfjwt = JWTHS256.buildJWT(subject, authOfjson);
        response.addHeader("jwt", authOfjwt);
        //跨域時(shí)允許header攜帶jwt
        response.addHeader("Access-Control-Expose-Headers" ,"jwt");
        redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);
        //---------互踢start-------------
        // 在緩存中傳入key="R_V_USERIDLOGINKEY_" + userId + "_LOGIN",value=SecurityConstants.getJwtKey(subject),有新登錄時(shí)如果用戶一樣則把緩存里之前的jwt刪除,這個(gè):(redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);)
        log.info("設(shè)置jwt,并在緩存中傳入:{}",SecurityConstants.getJwtKey(subject));
        String uuid = (String) redisTemplate.opsForValue().get(RedisKey.getUserIdKey(sysUser.getId()));
        log.info("查詢?cè)衘wt:{}",uuid);
        if(!SecurityConstants.getJwtKey(subject).equals(uuid)&& Objects.nonNull(uuid)){
            assert uuid != null;
            redisTemplate.delete(uuid);
            log.info("刪除原有jwt:{}",uuid);
        }
        redisTemplate.opsForValue().set(RedisKey.getUserIdKey(sysUser.getId()), SecurityConstants.getJwtKey(subject),60, TimeUnit.MINUTES);
        log.info("在緩存里塞入新jwt:{}",SecurityConstants.getJwtKey(subject));
        //---------互踢end----------------------
        response.setContentType("application/json;charset=utf-8");
        PrintWriter out = response.getWriter();

        User returnSysUser = new User();
        returnSysUser
                .setName(sysUser.getName())
                .setCurrentOrg(sysUser.getCurrentOrg())
                .setOrgIdMapRoleList(sysUser.getOrgIdMapRoleList())
                .setCurrentMenuList(sysUser.getCurrentMenuList())
                .setOrgList(sysUser.getOrgList());

        out.write(jacksonObjectMapper.writeValueAsString(new ReturnObject<>(this.getClass().getName(), ConstantOfReturnCode.GLOBAL_RESULT_SUCESS, "登錄成功", returnSysUser)));
        out.flush();
        out.close();
    }
}

package com.lc.gansu.security.component.jwt;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lc.gansu.framework.core.RedisKey;
import com.lc.gansu.security.component.SecurityConstants;
import com.lc.gansu.security.domain.User;
import com.lc.gansu.security.utility.JWTHS256;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.SecurityContextRepository;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
public class JwtSecurityContextRepository implements SecurityContextRepository {
    protected final Log logger = LogFactory.getLog(this.getClass());

    private final RedisTemplate<String, Object> redisTemplate;
    private final ObjectMapper jacksonObjectMapper;

    public JwtSecurityContextRepository(RedisTemplate<String, Object> redisTemplate, ObjectMapper jacksonObjectMapper) {
        this.redisTemplate = redisTemplate;
        this.jacksonObjectMapper = jacksonObjectMapper;
    }

    @Override
    public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
        HttpServletRequest request = requestResponseHolder.getRequest();
        return readSecurityContextFromJWT(request);
    }

    @Override
    public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) {
    }

    @Override
    public boolean containsContext(HttpServletRequest request) {
        return false;
    }

    private SecurityContext readSecurityContextFromJWT(HttpServletRequest request) {
        SecurityContext context = generateNewContext();
        String authenticationOfjwt = request.getHeader("jwt");
        if (StringUtils.isNotBlank(authenticationOfjwt)) {
            try {
                Map<String, Object> map = JWTHS256.vaildToken(authenticationOfjwt);
                if (Objects.nonNull(map) && map.size() == 2) {
                    String subject = (String) map.get("subject");
                    Boolean isExp = redisTemplate.hasKey(SecurityConstants.getJwtKey(subject));
                    if (Objects.nonNull(isExp) && isExp) {//redis key 未過(guò)期
                        redisTemplate.expire(SecurityConstants.getJwtKey(subject), 60, TimeUnit.MINUTES);//延期
                        String obj = (String) map.get("claim");
                        //AuthenticationAdapter authenticationAdapter=jacksonObjectMapper.readValue(obj, new TypeReference<>(){});
                        //Authentication authentication=AuthenticationAdapter.authenticationAdapter2Authentication(authenticationAdapter);
                        //Authentication authentication=jacksonObjectMapper.readValue(obj, new TypeReference<>(){});
                        //Authentication authentication=jacksonObjectMapper.readValue(obj,Authentication.class);
                        User sysUser = jacksonObjectMapper.readValue(obj, new TypeReference<User>() {
                        });
                        Authentication authentication = new UsernamePasswordAuthenticationToken(sysUser, null, sysUser.getAuthorities());
                        context.setAuthentication(authentication);
                        //-----互踢start-------
                        if(Objects.nonNull(RedisKey.getUserIdKey(sysUser.getId()))) redisTemplate.expire(RedisKey.getUserIdKey(sysUser.getId()), 60, TimeUnit.MINUTES);
                        //-----互踢end---------
                        //if(obj instanceof Authentication){
                        //context.setAuthentication((Authentication)obj);
                        //}else log.error("jwt包含authentication的數(shù)據(jù)非法");
                    } else log.error("jwt數(shù)據(jù)過(guò)期");
                } else log.error("jwt數(shù)據(jù)非法");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(e.getLocalizedMessage());
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("No JWT was available from the HttpServletRequestHeader!");
            }
        }
        return context;
    }

    protected SecurityContext generateNewContext() {
        return SecurityContextHolder.createEmptyContext();
    }
}

package com.lc.gansu.framework.core;

/**
 * TODO
 *
 * @author songtianxiong
 * @version 1.0
 * @date 2021/11/16 19:15
 */
public class RedisKey {
    //線上投放計(jì)劃反饋結(jié)果催辦
    public static String getOlpmIdAndUserIdRedisKey(Long OlpmId, Long userId) {
        return "R_V_OLPMURGE_" + OlpmId + "_" + userId;
    }

    //催辦
    public static String getOdpIdAndUserIdRedisKey(Long OdpId, Long userId) {
        return "R_V_ODPMURGE_" + OdpId + "_" + userId;
    }

    //催辦
    public static String getJwtAndUrl(String jwt, String url) {
        return "R_V_REPEAT_" + jwt + "_" + url;
    }

    //用戶登錄互踢
    public static String getUserIdKey(Long userId) {
        return "R_V_USERIDLOGINKEY_" + userId + "_LOGIN";
    }
}

---------------------------關(guān)鍵詞:互踢

關(guān)鍵代碼:

        //---------互踢start-------------
        // 在緩存中傳入key="R_V_USERIDLOGINKEY_" + userId + "_LOGIN",value=SecurityConstants.getJwtKey(subject),有新登錄時(shí)如果用戶一樣則把緩存里之前的jwt刪除,這個(gè):(redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);)
        log.info("設(shè)置jwt,并在緩存中傳入:{}",SecurityConstants.getJwtKey(subject));
        String uuid = (String) redisTemplate.opsForValue().get(RedisKey.getUserIdKey(sysUser.getId()));
        log.info("查詢?cè)衘wt:{}",uuid);
        if(!SecurityConstants.getJwtKey(subject).equals(uuid)&& Objects.nonNull(uuid)){
            assert uuid != null;
            redisTemplate.delete(uuid);
            log.info("刪除原有jwt:{}",uuid);
        }
        redisTemplate.opsForValue().set(RedisKey.getUserIdKey(sysUser.getId()), SecurityConstants.getJwtKey(subject),60, TimeUnit.MINUTES);
        log.info("在緩存里塞入新jwt:{}",SecurityConstants.getJwtKey(subject));
        //---------互踢end----------------------
                        //-----互踢start-------
                        if(Objects.nonNull(RedisKey.getUserIdKey(sysUser.getId()))) redisTemplate.expire(RedisKey.getUserIdKey(sysUser.getId()), 60, TimeUnit.MINUTES);
                        //-----互踢end---------
    //用戶登錄互踢
    public static String getUserIdKey(Long userId) {
        return "R_V_USERIDLOGINKEY_" + userId + "_LOGIN";
    }

到此這篇關(guān)于springSecurity+jwt中實(shí)現(xiàn)互踢功能的文章就介紹到這了,更多相關(guān)springSecurity+jwt互踢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實(shí)現(xiàn)簡(jiǎn)單美女拼圖游戲

    java實(shí)現(xiàn)簡(jiǎn)單美女拼圖游戲

    這篇文章主要介紹了java實(shí)現(xiàn)簡(jiǎn)單美女拼圖游戲的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • Java基礎(chǔ)詳解之集合框架工具Collections

    Java基礎(chǔ)詳解之集合框架工具Collections

    這篇文章主要介紹了Java基礎(chǔ)詳解之集合框架工具Collections,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-04-04
  • JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    JavaWeb中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    這篇文章主要介紹了JavaWeb中struts2文件上傳下載功能的實(shí)現(xiàn),在Web應(yīng)用系統(tǒng)開(kāi)發(fā)中,文件上傳和下載功能是非常常用的功能,需要的朋友可以參考下
    2016-05-05
  • JFinal極速開(kāi)發(fā)框架使用筆記分享

    JFinal極速開(kāi)發(fā)框架使用筆記分享

    下面小編就為大家分享一篇JFinal極速開(kāi)發(fā)框架使用筆記,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值

    java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值

    這篇文章主要介紹了java如何刪除以逗號(hào)隔開(kāi)的字符串中某一個(gè)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java?棧與隊(duì)列實(shí)戰(zhàn)真題訓(xùn)練

    Java?棧與隊(duì)列實(shí)戰(zhàn)真題訓(xùn)練

    在編寫(xiě)程序的時(shí)候,對(duì)于棧與隊(duì)列的應(yīng)用需要熟練的掌握,這樣才能夠確保寫(xiě)出來(lái)的代碼有質(zhì)量。本文小編就以幾個(gè)題目詳細(xì)說(shuō)說(shuō)Java中的棧與隊(duì)列,需要的朋友可以參考一下
    2022-04-04
  • 詳細(xì)解讀spring中的@Resource注解

    詳細(xì)解讀spring中的@Resource注解

    這篇文章主要介紹了詳細(xì)解讀spring中的@Resource注解,此注解來(lái)源于JSR規(guī)范(Java?Specification?Requests),其作用是找到依賴的組件注入到應(yīng)用來(lái),它利用了JNDI技術(shù)查找所需的資源,需要的朋友可以參考下
    2023-10-10
  • springmvc組件中的HandlerMapping解析

    springmvc組件中的HandlerMapping解析

    這篇文章主要介紹了springmvc九大組件中的HandlerMapping解析,HandlerMapping表示的是一個(gè)URL與一個(gè)Handler(可以簡(jiǎn)單的理解為Controller中有@RequestMapping注解的方法)之間的映射關(guān)系,需要的朋友可以參考下
    2023-09-09
  • Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)

    Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)

    下面小編就為大家?guī)?lái)一篇Java VisualVM監(jiān)控遠(yuǎn)程JVM(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Java?CyclicBarrier錯(cuò)誤使用的實(shí)例

    Java?CyclicBarrier錯(cuò)誤使用的實(shí)例

    文章描述了一個(gè)Java程序使用CyclicBarrier實(shí)現(xiàn)兩個(gè)線程交替打印字母和數(shù)字時(shí)遇到的問(wèn)題,由于線程執(zhí)行順序不當(dāng),導(dǎo)致輸出結(jié)果與預(yù)期不符,通過(guò)調(diào)整線程的等待和打印順序,解決了問(wèn)題,文章還提供了一個(gè)控制流圖來(lái)詳細(xì)解釋修改前后的程序邏輯
    2025-01-01

最新評(píng)論

长葛市| 枣阳市| 延吉市| 台中市| 诸城市| 库尔勒市| 铜山县| 聂荣县| 邮箱| 汕尾市| 梁平县| 石泉县| 扬州市| 和顺县| 张家口市| 安丘市| 寻乌县| 武平县| 上思县| 固始县| 英超| 昌图县| 行唐县| 剑河县| 云梦县| 东乌珠穆沁旗| 重庆市| 峡江县| 定远县| 星子县| 五家渠市| 海丰县| 和静县| 交口县| 常州市| 晋宁县| 银川市| 汾西县| 方正县| 桑日县| 陇西县|