1. 程式人生 > >微服務springcloud—Feign修改使用者微服務和修改電影微服務

微服務springcloud—Feign修改使用者微服務和修改電影微服務

修改使用者為服務

1.複製專案microservice-provider-user,將ArtfactId修改為microservice-provider-user-with-auth。

2.微服務新增如下依賴

	 <dependency>
      	 <groupId>org.springframework.cloud</groupId>
      	 <artifactId>spring-cloud-starter-security</artifactId>
    	 <version>2.0.1.RELEASE</version>
    </dependency>

3.建立Spring Security的配置類

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        //所有的請求,都需要經過HTTP basic認證
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        //明文編碼器。這是一個不做任何操作的密碼編碼器,是Spring提供給我們做明文測試的
        // A password encoder that does nothing. Useful for testing where working with plain text
        return NoOpPasswordEncoder.getInstance();
    }

    @Autowired
    private CustomUserDetailsService userDatailsService ;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userDatailsService).passwordEncoder(this.passwordEncoder());
    }

    @Component
    class CustomUserDetailsService implements UserDetailsService {
        /**
         * 模擬兩個賬號
         * 1. 賬號是user ,密碼是password1 角色是user-role
         * 2. 賬號是admin,密碼是password2 角色是admin-role
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
            if ("user".equals(username)){
                return new SecurityUser("user", "password1", "user-role");
            }else if ("admin".equals(username)){
                return new SecurityUser("admin", "password2", "admin-role");
            }else{
             return null;
            }
        }
    }

    class SecurityUser implements UserDetails{
        private static final long serialVersionUID = 1L;

        public SecurityUser(String username, String password, String role){
            super();
            this.username = username;
            this.password = password;
            this.role = role;
        }
        public SecurityUser(){
        }

        private Long id;
        private String username;
        private String password;
        private String role;


        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(this.role);
            authorities.add(authority);
            return authorities;
        }

        @Override
        public boolean isAccountNonExpired() {
            return true;
        }

        @Override
        public boolean isAccountNonLocked() {
            return true;
        }

        @Override
        public boolean isCredentialsNonExpired() {
            return true;
        }

        @Override
        public boolean isEnabled() {
            return true;
        }

        @Override
        public String getPassword() {
            return this.password;
        }

        @Override
        public String getUsername() {
            return this.username;
        }

        public Long getId() {
            return this.id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getRole() {
            return this.role;
        }

        public void setRole(String role) {
            this.role = role;
        }
    }

程式碼中模擬了兩個賬號: user和admin,他們的密碼分別是password1和password2,角色分別為user-role和admin-role。

4.修改Controller,在其中列印當前登入的使用者資訊。

@RestController
public class UserController {
  @Autowired
  private UserRepository userRepository;
  private static final Logger LOGGER =  LoggerFactory.getLogger(UserController.class
); @GetMapping("/{id}") public User findById(@PathVariable Long id) { Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if(principal instanceof UserDetails){ UserDetails user = (UserDetails) principal; Collection<? extends GrantedAuthority> collection = user.getAuthorities(); for (GrantedAuthority c : collection){ //列印當前登入使用者的資訊 UserController.LOGGER.info("當前使用者是{},角色是{}",user.getUsername(), c.getAuthority()); } }else{ //do other things } User findOne = this.userRepository.findById(id).get(); return findOne; } }

測試

1.啟動microservice-discovery-eureka。
2.啟動microservice-provider-user-with-auth。
3.訪問http://localhost:8000/1,會彈出登入對話方塊。
在這裡插入圖片描述

4.使用user/password1登入,可看到如下日誌。
在這裡插入圖片描述

5.使用admin/password2登入,可看到如下日誌。
在這裡插入圖片描述

修改電影微服務

1.複製專案microservice-consumer-movie-feign,將ArtifactId修改為microservice-consumer-movie-feign-manual。

2.去掉Feign介面UserFeignClient上的@FeignClient註解

3.去掉啟動類上@EnableFeignClients註解

4.修改Controller如下:

@Import(FeignClientsConfiguration.class)
@RestController
public class MovieController {
    private UserFeignClient userUserFeignClient;
    private UserFeignClient adminUserFeignClient;

    @Autowired
    public MovieController(Decoder decoder, Encoder encoder, Client client, Contract contract){
        //這邊的decoder、encoder、client、contract,可以Debug看看是什麼例項
        this.userUserFeignClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
            .requestInterceptor(new BasicAuthRequestInterceptor("user", "password1"))
             .target(UserFeignClient.class, "http://users/");
        this.adminUserFeignClient= Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
            .requestInterceptor(new BasicAuthRequestInterceptor("admin","password2"))
            .target(UserFeignClient.class, "http://users/");
    }

    @GetMapping("/user-user/{id}")
    public User findByIdUser(@PathVariable Long id){
        return this.userUserFeignClient.findById(id);
    }

    @GetMapping("/user-admin/{id}")
    public User findByIdAdmin(@PathVariable Long id){
        return this.adminUserFeignClient.findById(id);
    }
}

測試

1.啟動microservice-discovery-eureka。
2.啟動microservice-provider-user-with-auth。
3.啟動microservice-consumer-movie-feign-manual。
4.訪問http://localhost:8010/user-user/1,微服務列印如下日誌。
在這裡插入圖片描述

5.訪問http://localhost:8010/user-admin/1,微服務列印如下日誌。
在這裡插入圖片描述

本文大部分內容轉載自周立的《Spring Cloud與Docker微服務架構實戰》