美文网首页
java B2B2C Springcloud电子商务平台源码-自

java B2B2C Springcloud电子商务平台源码-自

作者: IT小跑兵 | 来源:发表于2019-01-30 10:43 被阅读4次

    feign的使用,可以简化服务之间的调用,让服务之间调用更加优雅,本文从feign自定义配置和创建feign完成服务之间复杂权限验证,来进一步理解和定制feign。
    需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 一零三八七七四六二六
    自定义配置

    创建Feign的配置类

    @Configuration
    public class FeignConfiguration{
         @Bean
         public Contract feignContract(){
             return new feign.Contract.Default();
        }
    
        @Bean
        public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){
             return new BasicAuthRequestInterceptor("user","password");
       }
    }
    

    说明:第一个@Bean配置是在FeignClient中的接口中使用Feign自带的注解; 第二个@Bean配置是在请求接口中要进行基于Http Basic的认证后才能调用。

    FeignClient接口引用配置

    @FeignClient(name="hello", configuration=FeignConfiguration.class)
    public interface HelloService{
        @RequestLine("GET /message")
        HelloMessage hello();
    }
    

    需要注意的是: FeignConfiguration类不能包含在主应用程序上下文的@ComponentScan中,否则该配置会被所有的@FeignClient共享。

    Ribbon的自定义配置中也需要注意这个问题。

    服务调用的复杂权限认证

    上面演示了服务之间可以通过自定义配置完成基于Http Basic的认证,但是不能满足根据不同的角色不同的用户执行不同的操作,即服务之间的调用有更复杂的权限要求,就不能满足要求了,这时候要针对feign做进一步的改进。

    引入spring-security(服务提供者)

     <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    

    关键权限配置(服务提供者)

    package com.example.helloauth.configuration;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    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;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.SimpleGrantedAuthority;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.crypto.password.NoOpPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    /**
     * @author billjiang 475572229@qq.com
     * @create 17-8-26
     */
    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception{
            http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
        }
    
    
        @Bean
        public PasswordEncoder passwordEncoder(){
            return NoOpPasswordEncoder.getInstance();
        }
    
        @Autowired
        private CustomUserDetailService userDetailService;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception{
            auth.userDetailsService(this.userDetailService).passwordEncoder(this.passwordEncoder());
        }
    
        @Component
        class CustomUserDetailService implements UserDetailsService{
            @Override
            public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
                if("user".equals(username)){
                    return new SecurityUser("user","123456","user-role");
                }else if("admin".equals(username)){
                    return new SecurityUser("admin","123456","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(){
    
            }
    
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                Collection<GrantedAuthority> authorities=new ArrayList<>();
                SimpleGrantedAuthority authority=new SimpleGrantedAuthority(this.role);
                authorities.add(authority);
                return authorities;
            }
    
    
            private Long id;
            private String username;
            private String password;
            private String role;
    
            public Long getId() {
                return id;
            }
    
            public void setId(Long id) {
                this.id = id;
            }
    
            @Override
            public String getUsername() {
                return username;
            }
    
            @Override
            public boolean isAccountNonExpired() {
                return true;
            }
    
            @Override
            public boolean isAccountNonLocked() {
                return true;
            }
    
            @Override
            public boolean isCredentialsNonExpired() {
                return true;
            }
    
            @Override
            public boolean isEnabled() {
                return true;
            }
    
            public void setUsername(String username) {
                this.username = username;
            }
    
            @Override
            public String getPassword() {
                return password;
            }
    
            public void setPassword(String password) {
                this.password = password;
            }
    
            public String getRole() {
                return role;
            }
    
            public void setRole(String role) {
                this.role = role;
            }
        }
    
    }
    

    启动项目hello-auth后,可以见到页面需要输入用户名和密码才能访问。

    服务消费者hello-auth-feign修改

    去掉启动类上的@EnableFeignClients注解

    去掉接口的@FeignClient的注解

    package com.example.helloauthconsumerfeign.service;
    
    import com.example.helloauthconsumerfeign.model.User;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    /**
     * @author billjiang 475572229@qq.com
     * @create 17-8-23
     */
    //@FeignClient(value="hello-auth")
    public interface HelloAuthService {
    
        @GetMapping("/{id}")
        User findById(@PathVariable("id") Long id);
    
    
    }
    

    编写Controller类如下

    package com.example.helloauthconsumerfeign.controller;
    
    import com.example.helloauthconsumerfeign.model.User;
    import com.example.helloauthconsumerfeign.service.HelloAuthService;
    import feign.Client;
    import feign.Contract;
    import feign.Feign;
    import feign.auth.BasicAuthRequestInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import feign.codec.Decoder;
    import feign.codec.Encoder;
    import org.springframework.cloud.netflix.feign.FeignClientsConfiguration;
    import org.springframework.context.annotation.Import;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController;
    
    
    /**
     * @author billjiang 475572229@qq.com
     * @create 17-8-26
     */
    @Import(FeignClientsConfiguration.class)
    @RestController
    public class HelloAuthFeignController {
        private HelloAuthService userAuthService;
    
        private HelloAuthService adminAuthService;
    
        @Autowired
        public HelloAuthFeignController(Decoder decoder, Encoder encoder, Client client, Contract contract){
            this.userAuthService= Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
                    .requestInterceptor(new BasicAuthRequestInterceptor("user","123456"))
                    .target(HelloAuthService.class,"http://hello-auth/");
    
            this.adminAuthService= Feign.builder().client(client).encoder(encoder).decoder(decoder).contract(contract)
                    .requestInterceptor(new BasicAuthRequestInterceptor("admin","123456"))
                    .target(HelloAuthService.class,"http://hello-auth/");
        }
    
        @GetMapping("/user/{id}")
        public User findByIdUser(@PathVariable Long id){
            return this.userAuthService.findById(id);
        }
    
    
        @GetMapping("/admin/{id}")
        public User findByIdAdmin(@PathVariable Long id){
            return this.adminAuthService.findById(id);
        }
    
    
    }
    

    消费者调用
    在浏览器器分别输入http://localhost:8031/admin/1http://localhost:8031/user/2则可以完成服务之间授权的调用。
    在实际业务中会根据不同的角色,执行不同的业务操作,基于以上示例可以在服务之间完成复杂的服务鉴权。

    java B2B2C Springcloud电子商务平台源码

    相关文章

      网友评论

          本文标题:java B2B2C Springcloud电子商务平台源码-自

          本文链接:https://www.haomeiwen.com/subject/csmqsqtx.html