微服务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微服务架构实战》

猜你喜欢

转载自blog.csdn.net/weixin_43439494/article/details/83617136