直接上代碼吧,Eureka Server端主要依賴的版本:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> <version>2.3.1.RELEASE</version> </dependency>
Eureka Server端的application.yml配置
server: port: 8761 eureka: server:
# 這裏只是爲了測試方便才修改的無效服務剔除時間間隔,生產環境儘量不要改 eviction-interval-timer-in-ms: 3000 client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://user:pwd123@localhost:8761/eureka/ spring: application: name: discovery-eureka-auth cloud: loadbalancer: ribbon: enabled: false inetutils: # preferred-networks: # - 192.168.0 ignored-interfaces: - VM.* security: user: name: user password: pwd123
對於現在較新的版本的Spring Security的security.basic.enabled配置項已經不可用了,要配置該屬性可以通過繼承並重寫 WebSecurityConfigurerAdapter :
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; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .httpBasic() .and() .csrf().ignoringAntMatchers("/eureka/**"); } }
引入新版的Spring Security後會自動開啓CSRF安全驗證,默認所有請求都要求提供CSRF的token,這就導致Eureka Client啓動後向Eureka Server進行服務註冊時也被要求提供CSRF的token,但是Eureka Client並不會生成CSRF要的token,目前也沒看到手工讓Eureka Client攜帶token的機制,
最終導致Eureka Client向Eureka Server服務註冊失敗,出現類似下面的異常:
2020-07-10 22:32:43.561 ERROR 21416 --- [tbeatExecutor-0] c.n.d.s.t.d.RedirectingEurekaHttpClient : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://user:pwd123@localhost:8761/eureka/}
解決該異常的方法就是重寫 WebSecurityConfigurerAdapter時,設置CSRF忽略掉與eureka相關的路徑(上文代碼中的.csrf().ignoringAntMatchers("/eureka/**")),當然也可以直接禁用掉CSRF,但不建議這麼做:
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; @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .httpBasic() .and() .csrf().disable();//不建議完全禁用掉csrf } }
Eureka Client端只要修改一下eureka.client.service-url.defaultZone就可以了:
eureka: instance:
# 這裏只是爲了測試方便修改的服務租期相關時間,生產環境不要改 lease-expiration-duration-in-seconds: 10 lease-renewal-interval-in-seconds: 5 prefer-ip-address: true client: service-url: defaultZone: http://user:pwd123@localhost:8761/eureka/