91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用springSecurity+jwt實現互踢功能

發布時間:2021-11-24 16:28:22 來源:億速云 閱讀:196 作者:小新 欄目:開發技術

小編給大家分享一下如何使用springSecurity+jwt實現互踢功能,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

jwt介紹:

        JWT是一種用于雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規范。JWT作為一個開放的標準( RFC 7519 ),定義了一種簡潔的,自包含的方法用于通信雙方之間以Json對象的形式安全的傳遞信息。

jwt認證流程介紹:

1. 用戶使用賬號和面發出post請求; 

2. 服務器使用私鑰創建一個jwt; 

3. 服務器返回這個jwt給瀏覽器; 

4. 瀏覽器將該jwt串在請求頭中像服務器發送請求; 

5. 服務器驗證該jwt; 

6. 返回響應的資源給瀏覽器。

如何使用springSecurity+jwt實現互踢功能

一.思路:

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

現在的互踢:
1.后臺在登陸成功后,用用戶id組成一個key,查詢redis緩存中的value
2.和新的jwt比較,如果不一樣則把查到的jwt當做key從redis中刪掉,就是上面第三步存儲的
3.把用戶id組成一個key,把上面jwt當做value傳入緩存中
4.在上面的第5步,也重置下我們這里存儲的值

*上面 指的是原來的實現用戶登錄態

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);
        //跨域時允許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),有新登錄時如果用戶一樣則把緩存里之前的jwt刪除,這個:(redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);)
        log.info("設置jwt,并在緩存中傳入:{}",SecurityConstants.getJwtKey(subject));
        String uuid = (String) redisTemplate.opsForValue().get(RedisKey.getUserIdKey(sysUser.getId()));
        log.info("查詢原有jwt:{}",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 未過期
                        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的數據非法");
                    } else log.error("jwt數據過期");
                } else log.error("jwt數據非法");
            } 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 {
    //線上投放計劃反饋結果催辦
    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";
    }
}

---------------------------關鍵詞:互踢

關鍵代碼:

//---------互踢start-------------
        // 在緩存中傳入key="R_V_USERIDLOGINKEY_" + userId + "_LOGIN",value=SecurityConstants.getJwtKey(subject),有新登錄時如果用戶一樣則把緩存里之前的jwt刪除,這個:(redisTemplate.boundValueOps(SecurityConstants.getJwtKey(subject)).set("w", 60, TimeUnit.MINUTES);)
        log.info("設置jwt,并在緩存中傳入:{}",SecurityConstants.getJwtKey(subject));
        String uuid = (String) redisTemplate.opsForValue().get(RedisKey.getUserIdKey(sysUser.getId()));
        log.info("查詢原有jwt:{}",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";
    }

以上是“如何使用springSecurity+jwt實現互踢功能”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

曲阜市| 东丽区| 沧源| 富民县| 本溪市| 阿克| 桃源县| 大宁县| 南澳县| 东乌珠穆沁旗| 慈溪市| 六枝特区| 长汀县| 巴南区| 都安| 梨树县| 长泰县| 廉江市| 台湾省| 卢湾区| 始兴县| 常宁市| 乡城县| 湘潭市| 龙口市| 浮梁县| 张家口市| 舒城县| 鄂尔多斯市| 靖西县| 漳浦县| 昌图县| 南木林县| 黑水县| 高青县| 盖州市| 汉中市| 招远市| 开阳县| 崇礼县| 南通市|