国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCloudGateWay+nacos+redis+springsecurity實(shí)現(xiàn)多微服務(wù)統(tǒng)一授權(quán)認(rèn)證

這篇具有很好參考價(jià)值的文章主要介紹了SpringCloudGateWay+nacos+redis+springsecurity實(shí)現(xiàn)多微服務(wù)統(tǒng)一授權(quán)認(rèn)證。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

之前做的大部分都是基于單體的springboot項(xiàng)目,對(duì)于權(quán)限這一塊直接套用springsecurity就可以搞定了

但是現(xiàn)在隨著微服務(wù)分布式架構(gòu)的流行,越來(lái)越多的項(xiàng)目都拆解成一個(gè)個(gè)的微服務(wù),因此需要重構(gòu)權(quán)限這一塊,這里我采用的是在網(wǎng)關(guān)gateway層進(jìn)行認(rèn)證授權(quán),根據(jù)認(rèn)證結(jié)果以及角色來(lái)判斷是否放行該請(qǐng)求:

大致圍繞下面三個(gè)需求:

  • 基于用戶-角色-權(quán)限控制
  • 權(quán)限粒度控制到具體的請(qǐng)求URL
  • 當(dāng)用戶的角色或者權(quán)限變動(dòng)后,已獲授權(quán)的用戶需要重新登錄授權(quán)

項(xiàng)目結(jié)構(gòu)如圖所示:

SpringCloudGateWay+nacos+redis+springsecurity實(shí)現(xiàn)多微服務(wù)統(tǒng)一授權(quán)認(rèn)證,redis,微服務(wù),java

認(rèn)證中心

springcloud-serve

登錄認(rèn)證授權(quán)等主要采用Spring security + redis+token機(jī)制,那么得首先配置WebSecurityConfig,這里看到的redis配置主要是為了滿足需求點(diǎn)3(當(dāng)用戶的角色或者權(quán)限變動(dòng)后,已獲授權(quán)的用戶需要重新登錄授權(quán))

登錄控制:

SpringCloudGateWay+nacos+redis+springsecurity實(shí)現(xiàn)多微服務(wù)統(tǒng)一授權(quán)認(rèn)證,redis,微服務(wù),java

對(duì)應(yīng)業(yè)務(wù)層:

@Override
    public ResponseResult login(LoginParam loginParam, HttpServletRequest request) {

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginParam.getName(),loginParam.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用戶名或密碼錯(cuò)誤");
        }
        LoginUser  loginUser = (LoginUser) authenticate.getPrincipal();

        // 生成當(dāng)前用戶登錄憑證
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        logger.info("當(dāng)前賬號(hào)對(duì)應(yīng)的token是: {}",token);

        SysUser sysUser = loginUser.getUser();
        Permission permission = new Permission();

        // 獲取當(dāng)前登錄用戶所屬的角色以及該角色可以訪問(wèn)哪些url,這里暫定寫死,正常來(lái)講是從數(shù)據(jù)庫(kù)獲取
        String roleName = "admin";
        List<String> urls = new ArrayList<>();
        urls.add("/api/serve/list");
        urls.add("/api/serve/test");
        permission.setRoleName("admin");
        permission.setUrls(urls);
        // 封裝
        redisTemplate.opsForValue().set(token,permission,600, TimeUnit.SECONDS);

        return new ResponseResult(200,"登錄成功",token);

    }

springsecurity配置

package com.cd.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.context.SecurityContextRepository;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) // 開啟權(quán)限校驗(yàn)注解
public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private AuthenticationEntryPoint authenticationEntryPoint;







    /**
     * 注入認(rèn)證管理器
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                //關(guān)閉csrf
                .csrf().disable()
                //不通過(guò)Session獲取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 對(duì)于登錄接口 允許匿名訪問(wèn)
                .antMatchers("/serve/login").permitAll();

        // 匿名訪問(wèn)的意思是,未登錄的狀態(tài)可以訪問(wèn)該路徑,但是如果是已經(jīng)登陸的狀態(tài),就不能訪問(wèn)該接口
        // 除上面外的所有請(qǐng)求全部需要鑒權(quán)認(rèn)證
    }


    /**
     * 自定義密碼加密解密方式
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

網(wǎng)關(guān)微服務(wù)層過(guò)濾器:

gateway

package com.cd.filter;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.cd.pojo.Permission;
import com.cd.pojo.ResponseResult;
import com.cd.pojo.SysUser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class AuthorizationFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;

    private static final Logger logger = LoggerFactory.getLogger(AuthorizationFilter.class);

    AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = request.getHeaders();

        //3. 如果是登錄請(qǐng)求則放行
        if (request.getURI().getPath().contains("/serve/login")) {
            return chain.filter(exchange);
        }

        String token = request.getHeaders().getFirst("token");
        if (StringUtils.isEmpty(token)){
             // 構(gòu)造錯(cuò)誤響應(yīng)體
            ResponseResult errorResponse = new ResponseResult(HttpStatus.UNAUTHORIZED.value(),"token無(wú)效");
            errorResponse.setCode(HttpStatus.UNAUTHORIZED.value());
            // 將錯(cuò)誤響應(yīng)體轉(zhuǎn)換為JSON字符串
            String json = null;
            json = JSONUtil.toJsonStr(errorResponse);
            // 設(shè)置響應(yīng)消息體
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
            DataBuffer buffer = response.bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8));
            return response.writeWith(Mono.just(buffer));
        }

        String path = request.getURI().getPath();
        logger.info("request path:{}", path);

        //3、判斷請(qǐng)求的URL是否有權(quán)限
        boolean b = hasPermission(token, path);
        if (!b){
            return getVoidMono(response, 403, "無(wú)訪問(wèn)權(quán)限");
        }
        return chain.filter(exchange);

    }


    private boolean hasPermission(String headerToken, String path){
        if (StringUtils.isEmpty(headerToken)){
            return false;
        }

        // 獲取token里面的內(nèi)容
        Permission permission = (Permission) redisTemplate.opsForValue().get(headerToken);
        if (Objects.isNull(permission)){
            return false;
        }

        // 取出權(quán)限信息
        List<String> urls = permission.getUrls();
        boolean b = urls.stream().anyMatch(authority -> antPathMatcher.match(authority, path));
        return b;

    }


    private Mono<Void> getVoidMono(ServerHttpResponse response, int i, String msg) {
        // 構(gòu)造錯(cuò)誤響應(yīng)體
        ResponseResult errorResponse = new ResponseResult(HttpStatus.FORBIDDEN.value(),msg);
        errorResponse.setCode(HttpStatus.FORBIDDEN.value());
        // 將錯(cuò)誤響應(yīng)體轉(zhuǎn)換為JSON字符串
        String json = null;
        json = JSONUtil.toJsonStr(errorResponse);
        // 設(shè)置響應(yīng)消息體
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        DataBuffer buffer = response.bufferFactory().wrap(json.getBytes(StandardCharsets.UTF_8));
        return response.writeWith(Mono.just(buffer));
    }


    @Override
    public int getOrder() {
        return 0;
    }
}

至此完成授權(quán)認(rèn)證:

代碼地址文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-686524.html

到了這里,關(guān)于SpringCloudGateWay+nacos+redis+springsecurity實(shí)現(xiàn)多微服務(wù)統(tǒng)一授權(quán)認(rèn)證的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包