1. zipkin-service工程
pom
- 最新版本的 zipkin-server不是這樣使用
- zipkin server要去官網下jar包
- 它現在不支援sdk的形式嵌入了
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/>
</parent>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.11.8</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.11.8</version>
</dependency>
<!--
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-storage-mysql</artifactId>
<version>2.4.1</version>
</dependency> -->
starter-web
eureka-client
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
yaml 和 enable
spring:
application:
name: zipkin-server
server:
port: 9411
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
#關閉自動收集web請求
management:
metrics:
web:
server:
auto-time-requests: false
@EnableEurekaClient
@EnableZipkinServer //已經過時
2. monitoring-server工程
pom
<dependency> config
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency> turbine
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency> actuator
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--hystrix-dashboard-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!--hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
yaml 和 main方法
spring:
application:
name: monitor-service
cloud:
config:
uri: http://localhost:8769
fail-fast: true
profiles:
active: pro
@SpringBootApplication //boot
@EnableEurekaClient //eurekaClient
@EnableDiscoveryClient //服務發現client,上面不用開啟了
@RestController //json controller
@EnableHystrix //hystrix
@EnableHystrixDashboard //hystrix dashboard
@EnableCircuitBreaker //circuit breaker 要在SpringCloud中使用斷路器,需要加上
@EnableTurbine //turbine
public class MonitorServiceApplication {
public static void main(String[] args) {
SpringApplication.run(MonitorServiceApplication.class, args);
}
}
沒有這個配置
feign:
hystrix:
enabled: true
3. uaa-service
流程
- 浏覽器 使用者名 + 密碼,到 user_blog, 加入 clientId,請求到 uaa 授權伺服器
- uaa驗證 clientId username 和 pwd,傳回JWT
- 浏覽器 得到 userInfo 和 JWT
- 浏覽器 header加入 JWT
- user_blog 解密JWT,驗證權限。 有權限 ,傳回資源
pom
<dependencies>
<!-- 配置-->
starter-config
starter-web
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
starter-netflix-eureka-client
<dependency> jpa
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
starter-actuator
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions> jks
<nonFilteredFileExtension>cert</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
yaml
spring:
application:
name: uaa-service
cloud:
config:
uri: http://localhost:8769
fail-fast: true
profiles:
active: pro
management:
security:
enabled: false #報錯
resources檔案下其他代碼
fzp-jwt.jks
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="INFO"/>
</configuration>
代碼
@EnableEurekaClient
1. entity
role
@Entity
public class Role implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Override
public String getAuthority() {
return name;
}
@Override
public String toString() {
return name;
}
}
user
@Entity
public class User implements UserDetails, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column
private String password;
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
private List<Role> authorities;
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Role> authorities) {
this.authorities = authorities;
}
}
2. dao 和 service
public interface UserDao extends JpaRepository<User, Long> {
User findByUsername(String username);
}
@Service
public class UserServiceDetail implements UserDetailsService {
@Autowired
private UserDao userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return userRepository.findByUsername(username);
}
}
3. config
oauth2 config繼承 Authorization Server Configurer Adapter
@Configuration
@Enable Authorization Server //開啟 認證server
public class OAuth2Config extends Authorization Server Configurer Adapter {
@Override //Client Details Service Configurer
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory() //記憶體
.withClient("uaa-service")
.secret("123456")
.scopes("service")
.autoApprove(true)
.authorizedGrantTypes("implicit","refresh_token", "password", "authorization_code") //4種都支援
.accessTokenValiditySeconds(24*3600);//24小時過期
}
@Override //Authorization Server Endpoints Configurer
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
//token Store,jwtToken enhancer
endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtTokenEnhancer()).authenticationManager(authenticationManager);
}
@Override//Authorization Server Security Configurer
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()").allowFormAuthenticationForClients()
.passwordEncoder(NoOpPasswordEncoder.getInstance());
/**
* 這就是為什麼以前,可以fein,卻不可以 postMMan吧
* 必須設定allowFormAuthenticationForClients 否則沒有辦法用postman擷取token
* 也需要指定密碼加密方式BCryptPasswordEncoder
*/
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean //token
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
@Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
//得到 key工程
KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("fzp-jwt.jks"), "fzp123".toCharArray());
//建立 converter
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
//設定 keyPair 。注意 這個.jks,可能已經過期,這裡會報錯,重新生成
converter.setKeyPair(keyStoreKeyFactory.getKeyPair("fzp-jwt"));
return converter;
}
}
resource server配置 Resource Server Configurer Adapter
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends Resource Server Configurer Adapter{
Logger log = LoggerFactory.getLogger(ResourceServerConfiguration.class);
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests() //下面這些請求,直接放行
.regexMatchers(".*swagger.*",".*v2.*",".*webjars.*","/user/login.*","/user/registry.*","/user/test.*",".*actuator.*").permitAll()
.antMatchers("/**").authenticated();
// .antMatchers("/**").permitAll();
}
}
security配置 WebSecurity Configurer Adapter
@Configuration
class WebSecurityConfig extends WebSecurity Configurer Adapter {
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authentication Manager Bean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
//CSRF:因為不再依賴于Cookie,是以你就不需要考慮對CSRF(跨站請求僞造)的防範。
http
.csrf().disable()
.exceptionHandling()
// .authenticationEntryPoint((request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED); //401
}
})
.and()
.authorizeRequests()
.antMatchers("/**").authenticated()
.and()
.httpBasic();
}
@Autowired
UserServiceDetail userServiceDetail;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userServiceDetail)
.passwordEncoder(new BCryptPasswordEncoder());
}
}
- UserUtils在後面指派代碼
- feign的 /oauth/token,依然在後面複制代碼
@FeignClient(value = "uaa-service")
@PostMapping(value = "/oauth/token")