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

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!

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

目錄

1. OAuth2.0授權(quán)服務(wù)

2. 資源服務(wù)

3. Gateway網(wǎng)關(guān)

4. 測(cè)試


?

在SpringSecurity+OAuth2.0 搭建認(rèn)證中心和資源服務(wù)中心-CSDN博客???????

基礎(chǔ)上整合網(wǎng)關(guān)和JWT實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)。

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

?

大致流程如下:

1、客戶(hù)端發(fā)出請(qǐng)求給網(wǎng)關(guān)獲取令牌

2、網(wǎng)關(guān)收到請(qǐng)求,直接轉(zhuǎn)發(fā)給授權(quán)服務(wù)

3、授權(quán)服務(wù)驗(yàn)證用戶(hù)名、密碼等一系列身份,通過(guò)則頒發(fā)令牌給客戶(hù)端

4、客戶(hù)端攜帶令牌請(qǐng)求資源,請(qǐng)求直接到了網(wǎng)關(guān)層

5、網(wǎng)關(guān)對(duì)令牌進(jìn)行校驗(yàn)(驗(yàn)簽、過(guò)期時(shí)間校驗(yàn)....)、鑒權(quán)(對(duì)當(dāng)前令牌攜帶的權(quán)限)和訪問(wèn)資源所需的權(quán)限進(jìn)行比對(duì),如果權(quán)限有交集則通過(guò)校驗(yàn),直接轉(zhuǎn)發(fā)給微服務(wù)

6、微服務(wù)進(jìn)行邏輯處理

1. OAuth2.0授權(quán)服務(wù)

導(dǎo)入依賴(lài)

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

application.yaml

server:
  port: 8080
spring:
  application:
    name: oauth2-cloud-auth-server
  cloud:
    nacos:
      ## 注冊(cè)中心配置
      discovery:
        # nacos的服務(wù)地址,nacos-server中IP地址:端口號(hào)
        server-addr: 127.0.0.1:8848
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/rbac?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

?這里展示部分代碼

AccessTokenConfig類(lèi)

/**
 * 令牌的配置
 */
@Configuration
public class AccessTokenConfig {
    /**
     * JWT的秘鑰
     * TODO 實(shí)際項(xiàng)目中需要統(tǒng)一配置到配置文件中,資源服務(wù)也需要用到
     */
    private final static String SIGN_KEY="jwt";

    /**
     * 令牌的存儲(chǔ)策略
     */
    @Bean
    public TokenStore tokenStore() {
        //使用JwtTokenStore生成JWT令牌
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * JwtAccessTokenConverter
     * TokenEnhancer的子類(lèi),在JWT編碼的令牌值和OAuth身份驗(yàn)證信息之間進(jìn)行轉(zhuǎn)換。
     * TODO:后期可以使用非對(duì)稱(chēng)加密
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        // 設(shè)置秘鑰
        converter.setSigningKey(SIGN_KEY);
        return converter;
    }

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

MyAuthorizationConfig類(lèi)

@Configuration
@EnableAuthorizationServer
public class MyAuthorizationConfig extends AuthorizationServerConfigurerAdapter {

   @Autowired
   private TokenStore tokenStore;
    /**
     * 客戶(hù)端存儲(chǔ)策略,這里使用內(nèi)存方式,后續(xù)可以存儲(chǔ)在數(shù)據(jù)庫(kù)
     */
    @Autowired
    private ClientDetailsService clientDetailsService;

    /**
     * Security的認(rèn)證管理器,密碼模式需要用到
     */
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    /**
     * 配置令牌訪問(wèn)的安全約束
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security
                //開(kāi)啟/oauth/token_key驗(yàn)證端口權(quán)限訪問(wèn)
                .tokenKeyAccess("permitAll()")
                //開(kāi)啟/oauth/check_token驗(yàn)證端口認(rèn)證權(quán)限訪問(wèn)
                .checkTokenAccess("permitAll()")
                //表示支持 client_id 和 client_secret 做登錄認(rèn)證
                .allowFormAuthenticationForClients();
    }
    //配置客戶(hù)端
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //內(nèi)存模式
        clients.inMemory()
                //客戶(hù)端id
                .withClient("test")
                //客戶(hù)端秘鑰
                .secret(new BCryptPasswordEncoder().encode("123456"))
                //資源id,唯一,比如訂單服務(wù)作為一個(gè)資源,可以設(shè)置多個(gè)
                .resourceIds("order")
                //授權(quán)模式,總共四種,1. authorization_code(授權(quán)碼模式)、password(密碼模式)、client_credentials(客戶(hù)端模式)、implicit(簡(jiǎn)化模式)
                //refresh_token并不是授權(quán)模式,
                .authorizedGrantTypes("authorization_code","password","client_credentials","implicit","refresh_token")
                //允許的授權(quán)范圍,客戶(hù)端的權(quán)限,這里的all只是一種標(biāo)識(shí),可以自定義,為了后續(xù)的資源服務(wù)進(jìn)行權(quán)限控制
                .scopes("all")
                //false 則跳轉(zhuǎn)到授權(quán)頁(yè)面
                .autoApprove(false)
                //授權(quán)碼模式的回調(diào)地址
                .redirectUris("http://www.baidu.com"); //可以and繼續(xù)添加客戶(hù)端
    }


    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices services = new DefaultTokenServices();
        //客戶(hù)端端配置策略
        services.setClientDetailsService(clientDetailsService);
        //支持令牌的刷新
        services.setSupportRefreshToken(true);
        //令牌服務(wù)
        services.setTokenStore(tokenStore);
        //access_token的過(guò)期時(shí)間
        services.setAccessTokenValiditySeconds(60 * 60 * 2);
        //refresh_token的過(guò)期時(shí)間
        services.setRefreshTokenValiditySeconds(60 * 60 * 24 * 3);

        //設(shè)置令牌增強(qiáng),使用jwt
        services.setTokenEnhancer(jwtAccessTokenConverter);
        return services;
    }
    /**
     * 授權(quán)碼模式的service,使用授權(quán)碼模式authorization_code必須注入
     */
    @Bean
    public AuthorizationCodeServices authorizationCodeServices() {
        //授權(quán)碼存在內(nèi)存中
        return new InMemoryAuthorizationCodeServices();
    }

    /**
     * 配置令牌訪問(wèn)的端點(diǎn)
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                //授權(quán)碼模式所需要的authorizationCodeServices
                .authorizationCodeServices(authorizationCodeServices())
                //密碼模式所需要的authenticationManager
                .authenticationManager(authenticationManager)
                //令牌管理服務(wù),無(wú)論哪種模式都需要
                .tokenServices(tokenServices())
                //只允許POST提交訪問(wèn)令牌,uri:/oauth/token
                .allowedTokenEndpointRequestMethods(HttpMethod.POST);
    }
}

SecurityConfig類(lèi)

/**
 * spring security的安全配置
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 加密算法
     */

    @Autowired
    JwtTokenUserDetailsService userDetailsService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //todo 允許表單登錄
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .csrf()
                .disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
       //從數(shù)據(jù)庫(kù)中查詢(xún)用戶(hù)信息
        auth.userDetailsService(userDetailsService);
    }



    /**
     * AuthenticationManager對(duì)象在OAuth2認(rèn)證服務(wù)中要使用,提前放入IOC容器中
     * Oauth的密碼模式需要
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

2. 資源服務(wù)

導(dǎo)入依賴(lài)

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
       </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

application.yaml

server:
  port: 8081
spring:
  application:
    name: oauth2-cloud-service
  cloud:
    nacos:
      ## 注冊(cè)中心配置
      discovery:
        # nacos的服務(wù)地址,nacos-server中IP地址:端口號(hào)
        server-addr: 127.0.0.1:8848

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

?AuthenticationFilter類(lèi)

@Component
public class AuthenticationFilter extends OncePerRequestFilter {
    /**
     * 具體方法主要分為兩步
     * 1. 解密網(wǎng)關(guān)傳遞的信息
     * 2. 將解密之后的信息封裝放入到request中
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //獲取請(qǐng)求頭中的用戶(hù)信息
        String token = request.getHeader("token");
        if (token!=null){
            //解密
            String json = Base64.decodeStr(token);
            JSONObject jsonObject = JSON.parseObject(json);
            //獲取用戶(hù)身份信息、權(quán)限信息
            String principal = jsonObject.getString("user_name");
            JSONArray tempJsonArray = jsonObject.getJSONArray("authorities");
            //權(quán)限
            String[] authorities =  tempJsonArray.toArray(new String[0]);
            //放入LoginVal
            LoginVal loginVal = new LoginVal();
          
            loginVal.setUsername(principal);
            loginVal.setAuthorities(authorities);
            
            //放入request的attribute中
            request.setAttribute("login_message",loginVal);
        }
        filterChain.doFilter(request,response);
    }
}

ServiceController類(lèi)

@RestController
public class ServiceController {

    @RequestMapping("/test")
    public LoginVal test(HttpServletRequest httpServletRequest){
       return  (LoginVal)httpServletRequest.getAttribute("login_message");
    }
}

3. Gateway網(wǎng)關(guān)

導(dǎo)入依賴(lài)

 <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-resource-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

application.yaml

server:
  port: 7000
spring:
  main:
    allow-bean-definition-overriding: true
  application:
    name: oauth2-cloud-gateway
  cloud:
    nacos:
      ## 注冊(cè)中心配置
      discovery:
        # nacos的服務(wù)地址,nacos-server中IP地址:端口號(hào)
        server-addr: 127.0.0.1:8848
    gateway:
      ## 路由
      routes:
        ## id只要唯一即可,名稱(chēng)任意
        - id: oauth2-cloud-auth-server
          uri: lb://oauth2-cloud-auth-server
          predicates:
            ## Path Route Predicate Factory斷言
            - Path=/oauth/**
        - id: oauth2-cloud-order
          uri: lb://oauth2-cloud-service
          predicates:
            ## Path Route Predicate Factory斷言
            - Path=/test/**

oauth2:
  cloud:
    sys:
      parameter:
        ignoreUrls:
          - /oauth/token
          - /oauth/authorize

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

?AccessTokenConfig類(lèi)

/**
 * 令牌的配置
 */
@Configuration
public class AccessTokenConfig {
    private final static String SIGN_KEY="jwt";

    /**
     * 令牌的存儲(chǔ)策略
     */
    @Bean
    public TokenStore tokenStore() {
        //使用JwtTokenStore生成JWT令牌
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * JwtAccessTokenConverter
     * TokenEnhancer的子類(lèi),在JWT編碼的令牌值和OAuth身份驗(yàn)證信息之間進(jìn)行轉(zhuǎn)換。
     * TODO:后期可以使用非對(duì)稱(chēng)加密
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        // 設(shè)置秘鑰
        converter.setSigningKey(SIGN_KEY);
        return converter;
    }
}

JwtAccessManager類(lèi)

@Slf4j
@Component
//經(jīng)過(guò)認(rèn)證管理器JwtAuthenticationManager認(rèn)證成功后,就需要對(duì)令牌進(jìn)行鑒權(quán),如果該令牌無(wú)訪問(wèn)資源的權(quán)限,則不允通過(guò)。
public class JwtAccessManager implements ReactiveAuthorizationManager<AuthorizationContext> {



    @Override
    public Mono<AuthorizationDecision> check(Mono<Authentication> mono, AuthorizationContext authorizationContext) {

        URI uri = authorizationContext.getExchange().getRequest().getURI();
        //設(shè)計(jì)權(quán)限角色,這里簡(jiǎn)單寫(xiě)一下,實(shí)際上應(yīng)該從數(shù)據(jù)庫(kù)或者緩存中獲取
        List<String> authorities = new ArrayList<>();
        authorities.add("ROLE_admin");
        //認(rèn)證通過(guò)且角色匹配的用戶(hù)可訪問(wèn)當(dāng)前路徑
        return mono
                //判斷是否認(rèn)證成功
                .filter(Authentication::isAuthenticated)
                //獲取認(rèn)證后的全部權(quán)限
                .flatMapIterable(Authentication::getAuthorities)
                .map(GrantedAuthority::getAuthority)
                //如果權(quán)限包含則判斷為true
                .any(authorities::contains)
                .map(AuthorizationDecision::new)
                .defaultIfEmpty(new AuthorizationDecision(false));
    }

}

JwtAuthenticationManager類(lèi)

/**
 * JWT認(rèn)證管理器,主要的作用就是對(duì)攜帶過(guò)來(lái)的token進(jìn)行校驗(yàn),比如過(guò)期時(shí)間,加密方式等
 * 一旦token校驗(yàn)通過(guò),則交給鑒權(quán)管理器進(jìn)行鑒權(quán)
 */
@Component
public class JwtAuthenticationManager implements ReactiveAuthenticationManager {
    /**
     * 使用JWT令牌進(jìn)行解析令牌
     */
    @Autowired
    private TokenStore tokenStore;

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        return Mono.justOrEmpty(authentication)
                .filter(a -> a instanceof BearerTokenAuthenticationToken)
                .cast(BearerTokenAuthenticationToken.class)
                .map(BearerTokenAuthenticationToken::getToken)
                .flatMap((accessToken -> {
                    OAuth2AccessToken oAuth2AccessToken = this.tokenStore.readAccessToken(accessToken);
                    //根據(jù)access_token從數(shù)據(jù)庫(kù)獲取不到OAuth2AccessToken
                    if (oAuth2AccessToken == null) {
                        return Mono.error(new InvalidTokenException("無(wú)效的token!"));
                    } else if (oAuth2AccessToken.isExpired()) {
                        return Mono.error(new InvalidTokenException("token已過(guò)期!"));
                    }
                    OAuth2Authentication oAuth2Authentication = this.tokenStore.readAuthentication(accessToken);
                    if (oAuth2Authentication == null) {
                        return Mono.error(new InvalidTokenException("無(wú)效的token!"));
                    } else {
                        return Mono.just(oAuth2Authentication);
                    }
                })).cast(Authentication.class);
    }
}

SecurityConfig類(lèi)

@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    /**
     * JWT的鑒權(quán)管理器
     */
    @Autowired
    private ReactiveAuthorizationManager<AuthorizationContext> accessManager;

    @Autowired
    private RequestAuthenticationEntryPoint requestAuthenticationEntryPoint;

    @Autowired
    private RequestAccessDeniedHandler requestAccessDeniedHandler;

    /**
     * 系統(tǒng)參數(shù)配置
     */
    @Autowired
    private SysParameterConfig sysConfig;

    /**
     * token校驗(yàn)管理器
     */
    @Autowired
    private ReactiveAuthenticationManager tokenAuthenticationManager;

    @Autowired
    private CorsFilter corsFilter;

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception{
        //認(rèn)證過(guò)濾器,放入認(rèn)證管理器tokenAuthenticationManager
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        http
                .httpBasic().disable()
                .csrf().disable()
                .authorizeExchange()
                //白名單直接放行
                .pathMatchers(ArrayUtil.toArray(sysConfig.getIgnoreUrls(),String.class)).permitAll()
                //其他的請(qǐng)求必須鑒權(quán),使用鑒權(quán)管理器
                .anyExchange().access(accessManager)
                //異常處理
                .and().exceptionHandling()
                .authenticationEntryPoint(requestAuthenticationEntryPoint)
                .accessDeniedHandler(requestAccessDeniedHandler)
                .and()
                // 跨域過(guò)濾器
                .addFilterAt(corsFilter, SecurityWebFiltersOrder.CORS)
                //token的認(rèn)證過(guò)濾器,用于校驗(yàn)token和認(rèn)證
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }
}

RequestAccessDeniedHandler

/**

 * 自定義返回結(jié)果:沒(méi)有權(quán)限訪問(wèn)時(shí)
 */
@Component
public class RequestAccessDeniedHandler implements ServerAccessDeniedHandler {
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException denied) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        String body= JSONUtil.toJsonStr(new ResultMsg(1005,"無(wú)權(quán)限訪問(wèn)",null));
        DataBuffer buffer =  response.bufferFactory().wrap(body.getBytes(Charset.forName("UTF-8")));
        return response.writeWith(Mono.just(buffer));
    }
}

GlobalAuthenticationFilter

/**
 * 全局過(guò)濾器,對(duì)token的攔截,解析token放入header中,便于下游微服務(wù)獲取用戶(hù)信息
 * 分為如下幾步:
 *  1、白名單直接放行
 *  2、校驗(yàn)token
 *  3、讀取token中存放的用戶(hù)信息
 *  4、重新封裝用戶(hù)信息,加密成功json數(shù)據(jù)放入請(qǐng)求頭中傳遞給下游微服務(wù)
 */
@Component
@Slf4j
public class GlobalAuthenticationFilter implements GlobalFilter, Ordered {
    /**
     * JWT令牌的服務(wù)
     */
    @Autowired
    private TokenStore tokenStore;



    /**
     * 系統(tǒng)參數(shù)配置
     */
    @Autowired
    private SysParameterConfig sysConfig;


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String requestUrl = exchange.getRequest().getPath().value();
        //1、白名單放行,比如授權(quán)服務(wù)、靜態(tài)資源.....
        if (checkUrls(sysConfig.getIgnoreUrls(),requestUrl)){
            return chain.filter(exchange);
        }

        //2、 檢查token是否存在
        String token = getToken(exchange);
        if (StringUtils.isBlank(token)) {
            return invalidTokenMono(exchange);
        }

        //3 判斷是否是有效的token
        OAuth2AccessToken oAuth2AccessToken;
        try {
            //解析token,使用tokenStore
            oAuth2AccessToken = tokenStore.readAccessToken(token);
            Map<String, Object> additionalInformation = oAuth2AccessToken.getAdditionalInformation();
            System.out.println(additionalInformation);

            //取出用戶(hù)身份信息
            String user_name = additionalInformation.get("user_name").toString();
            //獲取用戶(hù)權(quán)限
            List<String> authorities = (List<String>) additionalInformation.get("authorities");

            //將用戶(hù)名和權(quán)限進(jìn)行Base64加密
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("user_name", user_name);
            jsonObject.put("authorities",authorities);
            String base = Base64.encode(jsonObject.toJSONString());


           // ServerHttpRequest 中的 mutate 方法是用于創(chuàng)建一個(gè)修改后的請(qǐng)求對(duì)象的方法,而不改變?cè)颊?qǐng)求對(duì)象。這個(gè)方法是為了在處理請(qǐng)求過(guò)程中創(chuàng)建一個(gè)新的請(qǐng)求對(duì)象,以便進(jìn)行一些修改或增強(qiáng)。
            ServerHttpRequest tokenRequest = exchange.getRequest().mutate().header("token",base).build();
            ServerWebExchange build = exchange.mutate().request(tokenRequest).build();
            return chain.filter(build);
        } catch (InvalidTokenException e) {
            //解析token異常,直接返回token無(wú)效
            return invalidTokenMono(exchange);
        }


    }

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

    /**
     * 對(duì)url進(jìn)行校驗(yàn)匹配
     */
    private boolean checkUrls(List<String> urls,String path){
        AntPathMatcher pathMatcher = new AntPathMatcher();
        for (String url : urls) {
            if (pathMatcher.match(url,path))
                return true;
        }
        return false;
    }

    /**
     * 從請(qǐng)求頭中獲取Token
     */
    private String getToken(ServerWebExchange exchange) {
        String tokenStr = exchange.getRequest().getHeaders().getFirst("Authorization");
        if (StringUtils.isBlank(tokenStr)) {
            return null;
        }
        String token = tokenStr.split(" ")[1];
        if (StringUtils.isBlank(token)) {
            return null;
        }
        return token;
    }

    /**
     * 無(wú)效的token
     */
    private Mono<Void> invalidTokenMono(ServerWebExchange exchange) {
        return buildReturnMono(ResultMsg.builder()
                .code(1004)
                .msg("無(wú)效的token")
                .build(), exchange);
    }


    private Mono<Void> buildReturnMono(ResultMsg resultMsg, ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        byte[] bits = JSON.toJSONString(resultMsg).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset:utf-8");
        return response.writeWith(Mono.just(buffer));
    }
}

SysParameterConfig

@ConfigurationProperties(prefix = "oauth2.cloud.sys.parameter")
@Data
@Component
public class SysParameterConfig {
    /**
     * 白名單
     */
    private List<String> ignoreUrls;
}

4. 測(cè)試

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

?Gateway+Springsecurity+OAuth2.0+JWT 實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)!,OAuth2.0,gateway

代碼鏈接:Gateway+Springsecurity+OAuth2.0+JWT實(shí)現(xiàn)分布式統(tǒng)一認(rèn)證授權(quán)資源-CSDN文庫(kù)?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-820212.html

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

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(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)文章

  • SpringSecurity(二十四)--OAuth2:使用JWT和加密簽名(下)非對(duì)稱(chēng)密鑰加密

    SpringSecurity(二十四)--OAuth2:使用JWT和加密簽名(下)非對(duì)稱(chēng)密鑰加密

    由于上文對(duì)稱(chēng)密鑰涉及到的內(nèi)容比較多,所以這一節(jié)的非對(duì)稱(chēng)密鑰加密拆開(kāi)成這一節(jié)單獨(dú)講解。 所以大家盡量先閱讀完上一章的內(nèi)容后再瀏覽這一章內(nèi)容會(huì)更好。 本節(jié)將實(shí)現(xiàn)OAuth2身份驗(yàn)證的一個(gè)示例,其中授權(quán)服務(wù)器和資源服務(wù)器會(huì)使用一個(gè)非對(duì)稱(chēng)密鑰對(duì)來(lái)對(duì)令牌簽名和驗(yàn)

    2024年02月16日
    瀏覽(17)
  • 基于SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue實(shí)現(xiàn)的SaaS數(shù)字商城系統(tǒng)

    基于SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue實(shí)現(xiàn)的SaaS數(shù)字商城系統(tǒng)

    SaaS的英文全稱(chēng)是Software as a Service,意思是軟件即服務(wù) ,是云計(jì)算的其中一種服務(wù)模式 SaaS是一種通過(guò)Internet提供集中托管應(yīng)用程序的方式,企業(yè)用戶(hù)一般通過(guò)客戶(hù)端或網(wǎng)頁(yè)來(lái)使用,無(wú)需購(gòu)買(mǎi)、安裝或維護(hù)任何軟件及硬件,因此 SaaS應(yīng)用程序又被稱(chēng)為\\\"基于Web的軟件\\\" 或 \\\"托管軟件

    2024年01月20日
    瀏覽(24)
  • Spring Gateway + Oauth2 + Jwt網(wǎng)關(guān)統(tǒng)一鑒權(quán)

    Spring Gateway + Oauth2 + Jwt網(wǎng)關(guān)統(tǒng)一鑒權(quán)

    之前文章里說(shuō)過(guò),分布式系統(tǒng)的鑒權(quán)有兩種方式,一是在網(wǎng)關(guān)進(jìn)行統(tǒng)一的鑒權(quán)操作,二是在各個(gè)微服務(wù)里單獨(dú)鑒權(quán)。 第二種方式比較常見(jiàn),代碼網(wǎng)上也是很多。今天主要是說(shuō)第一種方式。 重要前提:需要收集各個(gè)接口的uri路徑和所需權(quán)限列表的對(duì)應(yīng)關(guān)系,并存入緩存。 服務(wù)

    2024年02月03日
    瀏覽(23)
  • SpringSecurity學(xué)習(xí)(八)OAuth2.0、授權(quán)服務(wù)器、資源服務(wù)器、JWT令牌的使用

    SpringSecurity學(xué)習(xí)(八)OAuth2.0、授權(quán)服務(wù)器、資源服務(wù)器、JWT令牌的使用

    OAuth2是一個(gè)認(rèn)證協(xié)議,SpringSecurity對(duì)OAuth2協(xié)議提供了響應(yīng)的支持,開(kāi)發(fā)者可以非常方便的使用OAuth2協(xié)議。 簡(jiǎn)介 四種授權(quán)模式 Spring Security OAuth2 GitHub授權(quán)登錄 授權(quán)服務(wù)器與資源服務(wù)器 使用JWT OAuth是一個(gè)開(kāi)放標(biāo)準(zhǔn),允許用戶(hù)讓第三方應(yīng)用訪問(wèn)該用戶(hù)在某一網(wǎng)站上存儲(chǔ)的私密資源

    2024年02月02日
    瀏覽(36)
  • oauth2.0第2季 分布式認(rèn)證與授權(quán)實(shí)現(xiàn)單點(diǎn)登錄

    oauth2.0第2季 分布式認(rèn)證與授權(quán)實(shí)現(xiàn)單點(diǎn)登錄

    1.使用jwttoken進(jìn)行令牌傳輸,資源服務(wù)器在本地怎么驗(yàn)證token? 1.1.1 oauth是什么 1.1.2?oauth的角色 1.1.3?oauth的認(rèn)證流程 1.1.4?oauth的4種模式 1.介紹單體架構(gòu)? 使用sesion保存會(huì)話信息的情況 2.前后端分離項(xiàng)目,調(diào)用方式 session架構(gòu)不適合前后端分離項(xiàng)目 3.解決辦法,引出oauth2.0 配置

    2024年02月11日
    瀏覽(21)
  • java版Spring Cloud+Mybatis+Oauth2+分布式+微服務(wù)+實(shí)現(xiàn)工程管理系統(tǒng)

    java版Spring Cloud+Mybatis+Oauth2+分布式+微服務(wù)+實(shí)現(xiàn)工程管理系統(tǒng)

    ?鴻鵠工程項(xiàng)目管理系統(tǒng) Spring Cloud+Spring Boot+Mybatis+Vue+ElementUI+前后端分離構(gòu)建工程項(xiàng)目管理系統(tǒng) 1. 項(xiàng)目背景 一、隨著公司的快速發(fā)展,企業(yè)人員和經(jīng)營(yíng)規(guī)模不斷壯大。為了提高工程管理效率、減輕勞動(dòng)強(qiáng)度、提高信息處理速度和準(zhǔn)確性,公司對(duì)內(nèi)部工程管理的提升提出了更高

    2024年02月07日
    瀏覽(26)
  • SpringSecurity+OAuth2.0

    SpringSecurity+OAuth2.0

    OAuth(Open Authorization)是一個(gè)關(guān)于授權(quán)(authorization)的開(kāi)放網(wǎng)絡(luò)標(biāo)準(zhǔn),允許用戶(hù)授權(quán)第三方應(yīng)用訪問(wèn)他們存儲(chǔ)在另外的服務(wù)提供者上的信息,而不需要將用戶(hù)名和密碼提供給第三方移動(dòng)應(yīng)用或分享他們數(shù)據(jù)的所有內(nèi)容。OAuth 在全世界得到廣泛應(yīng)用,目前的版本是 2.0 版。 簡(jiǎn)單

    2024年02月13日
    瀏覽(22)
  • SpringSecurity之Oauth2介紹

    SpringSecurity之Oauth2介紹

    第三方認(rèn)證技術(shù)方案最主要是解決 認(rèn)證協(xié)議的通用標(biāo)準(zhǔn)問(wèn)題 ,因?yàn)橐獙?shí)現(xiàn)跨系統(tǒng)認(rèn)證,各系統(tǒng)之間要遵循一定的接口協(xié)議。 OAUTH協(xié)議為用戶(hù)資源的授權(quán)提供了一個(gè)安全的、開(kāi)放而又簡(jiǎn)易的標(biāo)準(zhǔn)。同時(shí),任何第三方都可以使用OAUTH認(rèn)證服務(wù),任何服務(wù)提供商都可以實(shí)現(xiàn)自身的

    2023年04月09日
    瀏覽(25)
  • Spring Cloud Gateway 整合OAuth2.0 實(shí)現(xiàn)統(tǒng)一認(rèn)證授權(quán)

    Spring Cloud Gateway 整合OAuth2.0 實(shí)現(xiàn)統(tǒng)一認(rèn)證授權(quán) GateWay——向其他服務(wù)傳遞參數(shù)數(shù)據(jù) https://blog.csdn.net/qq_38322527/article/details/126530849 @EnableAuthorizationServer Oauth2ServerConfig 驗(yàn)證簽名 網(wǎng)關(guān)服務(wù)需要RSA的公鑰來(lái)驗(yàn)證簽名是否合法,所以認(rèn)證服務(wù)需要有個(gè)接口把公鑰暴露出來(lái) 接下來(lái)搭建網(wǎng)

    2024年02月13日
    瀏覽(23)
  • Spring Cloud Gateway + Oauth2 實(shí)現(xiàn)統(tǒng)一認(rèn)證和鑒權(quán)!

    Spring Cloud Gateway + Oauth2 實(shí)現(xiàn)統(tǒng)一認(rèn)證和鑒權(quán)!

    micro-oauth2-gateway:網(wǎng)關(guān)服務(wù),負(fù)責(zé)請(qǐng)求轉(zhuǎn)發(fā)和鑒權(quán)功能,整合Spring Security+Oauth2; micro-oauth2-auth:Oauth2認(rèn)證服務(wù),負(fù)責(zé)對(duì)登錄用戶(hù)進(jìn)行認(rèn)證,整合Spring Security+Oauth2; micro-oauth2-api:受保護(hù)的API服務(wù),用戶(hù)鑒權(quán)通過(guò)后可以訪問(wèn)該服務(wù),不整合Spring Security+Oauth2。 我們首先來(lái)搭建認(rèn)

    2024年01月16日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包