Spring Security OAuth2 實現登錄互踢


首先登錄互踢,就是同一賬號同時只能在一處登錄,所以實現方式就是沒登錄一次就更新一次token,確保之前的token失效

這里有兩種方式

1.修改源碼,將生成機制修改

下面屏蔽的代碼就是修改的代碼,這個在網上挺多的 參考:Spring Security OAuth2 實現登錄互踢 - 雲+社區 - 騰訊雲 (tencent.com)

 

 

// 重寫生成方法
    @Override
    @Transactional
    public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
        OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
        OAuth2RefreshToken refreshToken = null;
        if (existingAccessToken != null) {
            // 屏蔽token是否過期
//            if (!existingAccessToken.isExpired()) {
//                this.tokenStore.storeAccessToken(existingAccessToken, authentication);
//                return existingAccessToken;
//            }

//            if (existingAccessToken.getRefreshToken() != null) {
//                refreshToken = existingAccessToken.getRefreshToken();
//                this.tokenStore.removeRefreshToken(refreshToken);
//            }
            this.tokenStore.removeAccessToken(existingAccessToken);
        }

        if (refreshToken == null) {
            refreshToken = this.createRefreshToken(authentication);
        }
        else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
            ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken)refreshToken;
            if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
                refreshToken = this.createRefreshToken(authentication);
            }
        }

        OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
        this.tokenStore.storeAccessToken(accessToken, authentication);
        refreshToken = accessToken.getRefreshToken();
        if (refreshToken != null) {
            this.tokenStore.storeRefreshToken(refreshToken, authentication);
        }

        return accessToken;
    }

這樣基本就滿足了這個需求,但是在開發過程中遇到一個問題,就是源碼修改后在怎么部署到項目中

剛開始不知道,將有關的源碼全部復制到項目中

如圖

 

 其實這樣是比較重的方式,而且也沒有必要將所有代碼都引入

只需要引入最重用的那個文件,也就是 DefaultTokenServices.java,包括文件目錄都不變

直接運行,就可以看到效果了,就不貼圖了

如果覺得這種方式太重,可以重寫接口的方式

就是我要說的

直接上接口代碼,這里直接給出 登錄互踢和登錄的接口和實現

 

package com.adao.security.contorller;

import com.alibaba.fastjson.JSONObject;
import com.adao.security.common.ApiResult;
import com.adao.security.common.OperationLog;
import com.adao.security.service.AuthService;
import io.swagger.annotations.Api;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.Map;

/**
 * @author adao
 * @version 1.0
 * @date 2021/8/12
 * @description 認證控制相關接口
 */
@RestController
@RequestMapping("/oauth")
@Api(tags = "認證管理接口")
@Log4j2
public class AuthController {

    /**
     * 認證服務對象
     */
    @Resource
    private AuthService authService;

    /**
     * 重寫/oauth/token接口
     *
     * @param principal
     * @param parameters
     * @return accessToken
     */
    @PostMapping("/token")
    public ApiResult postAccessToken(Principal principal,
                                     @RequestParam Map<String, String> parameters) {
        // 判斷用戶名明碼是否正確,是否被鎖定等邏輯
        String username = parameters.get("username");
        String password = parameters.get("password");

        return authService.createAccessToken(principal, parameters);
    }

    /**
     * 認證注銷
     *
     * @param params token值
     * @return authLogout
     */
    @PostMapping(value = "/logout")
    @OperationLog(operModul = "安全認證-登錄注銷", operType = "LogOut", operDesc = "認證token信息注銷清除")
    public ApiResult logOut(@RequestBody JSONObject params) {
        String accessToken = params.getString("accessToken");
        return authService.logout(accessToken);
    }
}
AuthServiceImpl
package com.adao.security.service.impl;

import com.google.common.collect.Maps;
import com.adao.security.common.ApiCode;
import com.adao.security.common.ApiResult;
import com.adao.security.service.AuthService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.stereotype.Service;
import org.springframework.web.HttpRequestMethodNotSupportedException;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @author adao
 * @version 1.0
 * @date 2021/8/12
 * @description Oauth2認證邏輯實現類
 */
@Service("authService")
@Log4j2
public class AuthServiceImpl implements AuthService {

    @Autowired
    private RedisTokenStore redisTokenStore;

    @Autowired
    private RedisTokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @Override
    public ApiResult createAccessToken(Principal principal, Map<String, String> parameters) {

        // 刷新並廢棄掉當前token再重新生成token
        OAuth2AccessToken accessToken = null;
        try {
            accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
            String discardToken = accessToken.getValue();
            // 注銷token
            logout(discardToken);
            // 重新生成token
            accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
            log.info("create accessToken" + accessToken);
        } catch (HttpRequestMethodNotSupportedException e) {
            log.error("create accessToken error" + e.getMessage());
            return ApiResult.fail("鑒權失敗");
        }

        // token信息
        Map<String, Object> resultMap = Maps.newLinkedHashMap();
        resultMap.put("access_token", accessToken.getValue());
        resultMap.put("refresh_token", accessToken.getRefreshToken().getValue());
        resultMap.put("token_type", accessToken.getTokenType());
        resultMap.put("expires_in", accessToken.getExpiresIn());
        resultMap.put("scope", org.apache.commons.lang3.StringUtils.join(accessToken.getScope(), ","));
        resultMap.putAll(accessToken.getAdditionalInformation());
        // 權限信息

        List<String> list = getAuthoritiesList(accessToken);
        if (list != null && !list.isEmpty()) {
            resultMap.put("authorities", list);
            return ApiResult.ok(resultMap);
        } else {
            return ApiResult.fail("權限信息獲取異常", resultMap);
        }
    }


    /**
     * 通過accessToken注銷redis中用戶注冊token信息
     *
     * @param accessToken
     * @return ApiResult
     */
    @Override
    public ApiResult logout(String accessToken) {
        try {
            if (StringUtils.isNotBlank(accessToken)) {
                OAuth2AccessToken oAuth2AccessToken = redisTokenStore.readAccessToken(accessToken);
                if (null != oAuth2AccessToken) {
                    redisTokenStore.removeAccessToken(oAuth2AccessToken);
                    OAuth2RefreshToken oAuth2RefreshToken = oAuth2AccessToken.getRefreshToken();
                    redisTokenStore.removeRefreshToken(oAuth2RefreshToken);
                    redisTokenStore.removeAccessTokenUsingRefreshToken(oAuth2RefreshToken);
                    log.info("注銷成功. accessToken : {}, RefreshToken: {}", accessToken, oAuth2RefreshToken);
                } else {
                    log.info("注銷失敗. 無效accessToken : {}", accessToken);
                    return ApiResult.fail(ApiCode.ACCESS_TOKEN_INVALID);
                }
            }
            return ApiResult.ok();
        } catch (Exception e) {
            log.error("用戶注銷錯誤 :" + e.getMessage());
            return ApiResult.fail("用戶注銷錯誤 : " + e.getMessage());
        }
    }

    /**
     * 獲取用戶權限信息
     *
     * @param accessToken
     * @return List
     */
    private List<String> getAuthoritiesList(OAuth2AccessToken accessToken) {
        // 權限信息
        Collection<? extends GrantedAuthority> authorities =
                tokenStore.readAuthentication(accessToken).getUserAuthentication().getAuthorities();
        List<String> AuthoritiesList = new ArrayList<>();
        for (GrantedAuthority authority : authorities) {
            AuthoritiesList.add(authority.getAuthority());
        }
        return AuthoritiesList;
    }
}

 然后嘗試多次登錄 查看token變化還有redis中的token數據

 

-----------------------------

補充,上面

第一種是通過邏輯來解決互踢的需求,

第二種是通過源碼的方式

如果以上兩種都不想用還有第三種

如下,重寫接口並且同時修改源碼 

AuthController2
package com.adao.security.contorller;


import com.alibaba.fastjson.JSONObject;
import com.adao.security.common.ApiResult;
import com.adao.security.common.OperationLog;
import com.adao.security.service.AuthService;
import io.swagger.annotations.Api;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.*;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.UUID;


/**
 * @author adao
 * @version 1.0
 * @date 2021/8/12
 * @description 認證控制相關接口
 */
@RestController
@RequestMapping("/oauth")
@Api(tags = "認證管理接口")
@Log4j2
public class AuthController2 {

    /**
     * 認證服務對象
     */
    @Resource
    private AuthService authService;

    @Autowired
    private RedisTokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @Autowired
    private ClientDetailsService clientDetailsService;

//    @Autowired
//    private CreateTokenServiceHandler tokenServices;

    @Autowired
    public ApplicationContext applicationContext;

    private OAuth2RequestFactory oAuth2RequestFactory;

    private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator();

    private TokenGranter tokenGranter;

    private boolean supportRefreshToken = false;

    private int refreshTokenValiditySeconds = 60 * 60 * 60;
    private int accessTokenValiditySeconds = 60 * 60;

    private TokenEnhancer accessTokenEnhancer;

    /**
     * 認證注銷
     *
     * @param params token值
     * @return authLogout
     */
    @PostMapping(value = "/logout")
    @OperationLog(operModul = "安全認證-登錄注銷", operType = "LogOut", operDesc = "認證token信息注銷清除")
    public ApiResult logOut(@RequestBody JSONObject params) {
        String accessToken = params.getString("accessToken");
        return authService.logout(accessToken);
    }

    /**
     * 重寫login接口
     *
     * @param principal
     * @param parameters
     * @return
     * @throws HttpRequestMethodNotSupportedException
     */
    @PostMapping("/token")
    public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal,
                                                             @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        String username = parameters.get("username");
        String password = parameters.get("password");
        String grantType = parameters.get("grant_type");
        String scope = parameters.get("scope");

//        OAuth2AccessToken accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();

        String clientId = this.getClientId(principal);
        ClientDetails client = clientDetailsService.loadClientByClientId(clientId);

        TokenRequest tokenRequest = new TokenRequest(parameters, clientId, Collections.singleton(scope), grantType);

        tokenRequest = getTokenRequest(principal, parameters, tokenRequest);

        if (this.isRefreshTokenRequest(parameters)) {
            tokenRequest.setScope(OAuth2Utils.parseParameterList((String) parameters.get("scope")));
        }

        OAuth2Request storedOAuth2Request = tokenRequest.createOAuth2Request(client);

//        storedOAuth2Request.getRefreshTokenRequest().s

        OAuth2Authentication oa = new OAuth2Authentication(storedOAuth2Request, null);
//        OAuth2AccessToken token = tokenServices.createAccessToken(oa);
        OAuth2AccessToken token = createAccessToken(oa);

//        OAuth2AccessToken token = tokenServices.createAccessToken(oa);

//        CreateTokenServiceHandler tokenServiceHandler = applicationContext.getBean(CreateTokenServiceHandler.class);
//        OAuth2AccessToken token = tokenServiceHandler.createAccessToken(oa);


        System.out.println("client :" + client.getClientId());
        System.out.println("token###" + token);
        return this.getResponse(token);

    }

    //    private TokenRequest createTokenRequest(parameters, clientId, Collections.singleton(scope), grantType){
//        TokenRequest tokenRequest = new TokenRequest(parameters, clientId, Collections.singleton(scope), grantType);
//    }
    @Transactional
    public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
        OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
        OAuth2RefreshToken refreshToken = null;
        if (existingAccessToken != null) {
//            if (!existingAccessToken.isExpired()) {
//                this.tokenStore.storeAccessToken(existingAccessToken, authentication);
//                return existingAccessToken;
//            }
//
//            if (existingAccessToken.getRefreshToken() != null) {
//                refreshToken = existingAccessToken.getRefreshToken();
//                this.tokenStore.removeRefreshToken(refreshToken);
//            }

            this.tokenStore.removeAccessToken(existingAccessToken);
        }

        if (refreshToken == null) {
            refreshToken = createRefreshToken(authentication);
        } else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
            ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken;
            if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
                refreshToken = createRefreshToken(authentication);
            }
        }

        OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);
        this.tokenStore.storeAccessToken(accessToken, authentication);
        refreshToken = accessToken.getRefreshToken();
        if (refreshToken != null) {
            this.tokenStore.storeRefreshToken(refreshToken, authentication);
        }

        return accessToken;
    }

    private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
        DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
        int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request());
        if (validitySeconds > 0) {
            token.setExpiration(new Date(System.currentTimeMillis() + (long) validitySeconds * 1000L));
        }

        token.setRefreshToken(refreshToken);
        token.setScope(authentication.getOAuth2Request().getScope());
        return (OAuth2AccessToken) (accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token);
    }

    private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
        if (!this.isSupportRefreshToken(authentication.getOAuth2Request())) {
            return null;
        } else {
            int validitySeconds = this.getRefreshTokenValiditySeconds(authentication.getOAuth2Request());
            String value = UUID.randomUUID().toString();
            return (OAuth2RefreshToken) (validitySeconds > 0 ? new DefaultExpiringOAuth2RefreshToken(value, new Date(System.currentTimeMillis() + (long) validitySeconds * 1000L)) : new DefaultOAuth2RefreshToken(value));
        }
    }

    protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) {
        if (this.clientDetailsService != null) {
            ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
            Integer validity = client.getAccessTokenValiditySeconds();
            if (validity != null) {
                return validity;
            }
        }

        return this.accessTokenValiditySeconds;
    }


    protected boolean isSupportRefreshToken(OAuth2Request clientAuth) {
        if (this.clientDetailsService != null) {
            ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
            return client.getAuthorizedGrantTypes().contains("refresh_token");
        } else {
            return this.supportRefreshToken;
        }
    }

    protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) {
        if (this.clientDetailsService != null) {
            ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
            Integer validity = client.getRefreshTokenValiditySeconds();
            if (validity != null) {
                return validity;
            }
        }

        return this.refreshTokenValiditySeconds;
    }

    private TokenRequest getTokenRequest(Principal principal, @RequestParam Map<String, String> parameters, TokenRequest tokenRequest) {
        if (!(principal instanceof Authentication)) {
            throw new InsufficientAuthenticationException("There is no client authentication. Try adding an appropriate authentication filter.");
        } else {
            String clientId = this.getClientId(principal);
            ClientDetails authenticatedClient = this.getClientDetailsService().loadClientByClientId(clientId);
//            TokenRequest tokenRequest = createTokenRequest(parameters, authenticatedClient);
            if (clientId != null && !clientId.equals("") && !clientId.equals(tokenRequest.getClientId())) {
                throw new InvalidClientException("Given client ID does not match authenticated client");
            } else {
                if (authenticatedClient != null) {
                    this.oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
                }

                if (!StringUtils.hasText(tokenRequest.getGrantType())) {
                    throw new InvalidRequestException("Missing grant type");
                } else if (tokenRequest.getGrantType().equals("implicit")) {
                    throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
                } else {
                    if (this.isAuthCodeRequest(parameters) && !tokenRequest.getScope().isEmpty()) {
                        log.debug("Clearing scope of incoming token request");
                        tokenRequest.setScope(Collections.emptySet());
                    }

                    if (this.isRefreshTokenRequest(parameters)) {
                        tokenRequest.setScope(OAuth2Utils.parseParameterList((String) parameters.get("scope")));
                    }

                }
            }
            return tokenRequest;
        }
    }


    protected String getClientId(Principal principal) {
        Authentication client = (Authentication) principal;
        if (!client.isAuthenticated()) {
            throw new InsufficientAuthenticationException("The client is not authenticated.");
        } else {
            String clientId = client.getName();
            if (client instanceof OAuth2Authentication) {
                clientId = ((OAuth2Authentication) client).getOAuth2Request().getClientId();
            }

            return clientId;
        }
    }

    private ResponseEntity<OAuth2AccessToken> getResponse(OAuth2AccessToken accessToken) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cache-Control", "no-store");
        headers.set("Pragma", "no-cache");
        headers.set("Content-Type", "application/json;charset=UTF-8");
        return new ResponseEntity(accessToken, headers, HttpStatus.OK);
    }

    private boolean isRefreshTokenRequest(Map<String, String> parameters) {
        return "refresh_token".equals(parameters.get("grant_type")) && parameters.get("refresh_token") != null;
    }

    protected ClientDetailsService getClientDetailsService() {
        return this.clientDetailsService;
    }

    protected OAuth2RequestFactory getOAuth2RequestFactory() {
        return this.oAuth2RequestFactory;
    }

    private boolean isAuthCodeRequest(Map<String, String> parameters) {
        return "authorization_code".equals(parameters.get("grant_type")) && parameters.get("code") != null;
    }

    protected TokenGranter getTokenGranter() {
        return this.tokenGranter;
    }

}

 最后還有一種方式和第三種類似,但是沒有驗證 

onAuthenticationSuccess
package com.adao.security.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;

/**
 * @author adao
 * @version 1.0
 * @date 2021/8/13
 * @description 群組表(Group)表控制層
 */
@Log4j2
@Component
public class MyAuthenticationSucessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private ClientDetailsService clientDetailsService;
    @Autowired
    private AuthorizationServerTokenServices authorizationServerTokenServices;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        // 1. 從請求頭中獲取 ClientId
        String header = request.getHeader("Authorization");
        if (header == null || !header.startsWith("Basic ")) {
            throw new UnapprovedClientAuthenticationException("請求頭中無client信息");
        }

        String[] tokens = this.extractAndDecodeHeader(header, request);
        String clientId = tokens[0];
        String clientSecret = tokens[1];
        TokenRequest tokenRequest = null;
        // 2. 通過 ClientDetailsService 獲取 ClientDetails
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
        // 3. 校驗 ClientId和 ClientSecret的正確性
        if (clientDetails == null) {
            throw new UnapprovedClientAuthenticationException("clientId:" + clientId + "對應的信息不存在");
        } else if (!StringUtils.equals(clientDetails.getClientSecret(), clientSecret)) {
            throw new UnapprovedClientAuthenticationException("clientSecret不正確");
        } else {
            // 4. 通過 TokenRequest構造器生成 TokenRequest
            tokenRequest = new TokenRequest(new HashMap<>(), clientId, clientDetails.getScope(), "custom");
        }

        // 5. 通過 TokenRequest的 createOAuth2Request方法獲取 OAuth2Request
        OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
        // 6. 通過 Authentication和 OAuth2Request構造出 OAuth2Authentication
        OAuth2Authentication auth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

        // 7. 通過 AuthorizationServerTokenServices 生成 OAuth2AccessToken
        OAuth2AccessToken token = authorizationServerTokenServices.createAccessToken(auth2Authentication);

        // 8. 返回 Token
        log.info("登錄成功");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(new ObjectMapper().writeValueAsString(token));
    }

    private String[] extractAndDecodeHeader(String header, HttpServletRequest request) {
        byte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);

        byte[] decoded;
        try {
            decoded = Base64.getDecoder().decode(base64Token);
        } catch (IllegalArgumentException var7) {
            throw new BadCredentialsException("Failed to decode basic authentication token");
        }

        String token = new String(decoded, StandardCharsets.UTF_8);
        int delim = token.indexOf(":");
        if (delim == -1) {
            throw new BadCredentialsException("Invalid basic authentication token");
        } else {
            return new String[]{token.substring(0, delim), token.substring(delim + 1)};
        }
    }
}

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM