從零開始,手打一個權(quán)限管理系統(tǒng)(第十六章 認證與攔截)

第十六章 認證與攔截


前言

認證攔截還是跟之前單機版的一樣,代碼沒多少不一樣的地方,唯一有點區(qū)別的就是引入了feign來查詢用戶信息。


一、遠程服務(wù)調(diào)用Feign

  1. auth/pom.xm引入依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>
  1. 定義遠程服務(wù)調(diào)用接口
@FeignClient(contextId = "feignUpmsService", value = ServiceNameConstants.UMPS_API_SERVICE)
public interface FeignUpmsService {
    /**
     * 通過用戶名查詢用戶、角色信息
     * @param username 用戶名
     * @return R
     */
    @GetMapping(value = "/user/getInfo/{username}")
    Result<JwtUserDTO> getInfo(@PathVariable("username") String username);

}
  1. 開啟Fegin
@SpringBootApplication
@EnableFeignClients("com.ailot.cloud.auth.feign")
public class ServiceAuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceAuthApplication.class, args);
    }
}

二、配置普通服務(wù)的攔截規(guī)則

之前我們講過我們的權(quán)限攔截是放到每個服務(wù)的,所以還需要配置一個針對每個服務(wù)的安全配置類,這個安全配置類跟service-auth服務(wù)的大同小異,只不過只有會話攔截的功能。

  1. 在不配置的情況下訪問第三方服務(wù)接口,會重定向到此界面


    image.png
  2. 配置后訪問第三方服務(wù)接口


    image.png
  3. 第三方接口加白名單后訪問


    image.png

    image.png
  1. 安全配置代碼

/**
 * 普通服務(wù)的安全配置
 */
@Configuration
@EnableConfigurationProperties({PermitUrlProperties.class})
public class SpringSecurityServiceConfigurer {


    private final PermitUrlProperties permitUrlProperties;

    public SpringSecurityServiceConfigurer(PermitUrlProperties permitUrlProperties) {
        this.permitUrlProperties = permitUrlProperties;
    }

    /**
     * Configuration using lambdas
     *
     * @param http
     * @return
     * @throws Exception
     */
    @Bean
    @ConditionalOnMissingBean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        permitUrlProperties.getUrls()
                .forEach(url -> registry.antMatchers(url).permitAll());
        registry.anyRequest().authenticated();
        http
                //禁用表單登錄
                .formLogin().disable()
                // 關(guān)閉csrf
                .csrf((csrf) -> csrf.disable())
                //禁用session,JWT校驗不需要session
                .sessionManagement((session) -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .exceptionHandling((exception) -> exception
                        // 未授權(quán)異常處理
                        .accessDeniedHandler(new JwtAccessDeniedHandler()));
        http.addFilterAfter(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
        return new JwtAuthenticationTokenFilter(permitUrlProperties);
    }

三、配置Fegin調(diào)用免認證

前面的遠程服務(wù)調(diào)用是通過加白名單來放行的,但是內(nèi)部服務(wù)之間調(diào)用應(yīng)該是免認證,所以還需要配置一個內(nèi)部服務(wù)調(diào)用的標記,用來放行服務(wù)間的調(diào)用。
具體思路就是在feign調(diào)用的時候,在其請求的headr中添加一個標記;每次請求的時候先通過gateway清洗掉這個標記(fegin調(diào)用不通過gateway,清洗的目是為了防止非法請求),然后在具體服務(wù)里面攔截這個請求,驗證是否為內(nèi)部服務(wù)調(diào)用,部分代碼如下:

# feign 配置
feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: FULL
        # 內(nèi)部調(diào)用的header標記
        defaultRequestHeaders:
          X-FROM-INTERNAL-XXX: WOW
 // 清洗請求頭中的內(nèi)部調(diào)用標記,防止非法請求
        ServerHttpRequest request = exchange.getRequest().mutate()
                .headers(httpHeaders -> httpHeaders.remove(SecurityConstant.FROM))
                .build();
 /**
     * 判斷是否內(nèi)部調(diào)用
     * @param request
     * @return
     */
    public boolean isInner(HttpServletRequest request) {
        return request.getHeader(SecurityConstant.FROM) != null
                && request.getHeader(SecurityConstant.FROM).equalsIgnoreCase(SecurityConstant.FROM_IN);
    }

將這個方法加到權(quán)限攔截和token驗證的兩個類中,就可以實現(xiàn)內(nèi)部服務(wù)免認證訪問了。

測試可以發(fā)現(xiàn)直接訪問服務(wù)接口會提示未登錄,但通過feign訪問則可以正常返回數(shù)據(jù)。


image.png
image.png

當(dāng)前版本tag:2.0.1
代碼倉庫


四、 體驗地址

后臺數(shù)據(jù)庫只給了部分權(quán)限,報錯屬于正常!
想學(xué)的老鐵給點點關(guān)注吧?。?!
歡迎留言交流!?。?/p>

我是阿咕嚕,一個從互聯(lián)網(wǎng)慢慢上岸的程序員,如果喜歡我的文章,記得幫忙點個贊喲,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容