自定义feign配置与服务调用的安全验证

feign的使用 , 可以简化服务之间的调用 , 让服务之间调用更加优雅 , 本文从feign自定义配置和创建feign完成服务之间复杂权限验证 , 来进一步理解和定制feign 。
本文示例参考了《 Cloud与微服务架构实践》
自定义配置
@Configurationpublic class FeignConfiguration{@Beanpublic Contract feignContract(){return new feign.Contract.Default();}@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor(){return new BasicAuthRequestInterceptor("user","password");}}
说明:第一个@Bean配置是在中的接口中使用Feign自带的注解; 第二个@Bean配置是在请求接口中要进行基于Http Basic的认证后才能调用 。
@FeignClient(name="hello", configuration=FeignConfiguration.class)public interface HelloService{@RequestLine("GET /message")HelloMessage hello();}
需要注意的是: 类不能包含在主应用程序上下文的@中 , 否则该配置会被所有的@共享 。
【自定义feign配置与服务调用的安全验证】

自定义feign配置与服务调用的安全验证

文章插图
的自定义配置中也需要注意这个问题 。
服务调用的复杂权限认证
上面演示了服务之间可以通过自定义配置完成基于Http Basic的认证 , 但是不能满足根据不同的角色不同的用户执行不同的操作 , 即服务之间的调用有更复杂的权限要求 , 就不能满足要求了 , 这时候要针对feign做进一步的改进 。
代码示例见:hello-auth + hello-auth--feign的项目
以下是操作步骤:
- 引入-(服务提供者)
org.springframework.bootspring-boot-starter-security
自定义feign配置与服务调用的安全验证

文章插图
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 {@Overrideprotected void configure(HttpSecurity http) throws Exception{http.authorizeRequests().anyRequest().authenticated().and().httpBasic();}@Beanpublic PasswordEncoder passwordEncoder(){return NoOpPasswordEncoder.getInstance();}@Autowiredprivate CustomUserDetailService userDetailService;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception{auth.userDetailsService(this.userDetailService).passwordEncoder(this.passwordEncoder());}@Componentclass CustomUserDetailService implements UserDetailsService{@Overridepublic 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(){}@Overridepublic Collection