搭建资源服务器
引入依赖
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
添加资源服务器配置,添加@EnableResourceServer,并继承ResourceServerConfigurerAdapter
@Configuration
@EnableResourceServer//本身是作为oauth作为资源服务器存在的
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
/**
* 除了haha这个请求,其他的请求都要身份认证
* @param http
* @throws Exception
*/
@Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/haha").permitAll()
.antMatchers(HttpMethod.POST).access("#oauth2.hasAnyScope('write')")
.antMatchers(HttpMethod.GET).access("#oauth2.hasAnyScope('read')");
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("order-service");//对应认证服务器resourceIds配置
}
}
添加security配置,类似认证服务器配置
@Configuration
@EnableWebSecurity
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserDetailsService userDetailsService;
@Bean
public ResourceServerTokenServices tokenServices(){
RemoteTokenServices tokenServices=new RemoteTokenServices();
tokenServices.setClientId("orderApp");
tokenServices.setClientSecret("123456");
// tokenServices.setClientSecret(passwordEncoder.encode("123456"));
tokenServices.setCheckTokenEndpointUrl("http://localhost:8085/oauth/check_token");//认证服务器校验token的url
// 新增
tokenServices.setAccessTokenConverter(getAccessTokenConverter());//作用是把令牌转换成用户信息
return tokenServices;
}
private AccessTokenConverter getAccessTokenConverter() {
DefaultAccessTokenConverter tokenConverter=new DefaultAccessTokenConverter();
DefaultUserAuthenticationConverter authenticationConverter=new DefaultUserAuthenticationConverter();
authenticationConverter.setUserDetailsService(userDetailsService);
//把用户名转换成一个用户的信息
tokenConverter.setUserTokenConverter(authenticationConverter);
return tokenConverter;
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
OAuth2AuthenticationManager auth2AuthenticationManager=new OAuth2AuthenticationManager();
auth2AuthenticationManager.setTokenServices(tokenServices());
return auth2AuthenticationManager;
}
}
实现UserDetailsService接口实现类,拿到用户信息
@Component
public class UserDetilsServiceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user=new User();
user.setId(1L);
user.setUsername(username);
return user;
}
}
添加自定义User,并实现UserDetails
public class User implements UserDetails {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN");
}
/**
* 用户是不是没过期
* @return
*/
public boolean isAccountNonExpired() {
return true;
}
/**
* 这个账户是不是没被锁定
* @return
*/
public boolean isAccountNonLocked() {
return true;
}
/**
* 密码是不是没过期
* @return
*/
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 账户是不是可用的
* @return
*/
public boolean isEnabled() {
return true;
}
}
添加启动类
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
controller拿到用户信息,使用注解@AuthenticationPrincipal,拿到自定义User,从认证服务器获取的用户登录的用户信息,或者使用表达式,这样使用@AuthenticationPrincipal(expression = “#this.id”) Long id
@GetMapping("/{eid}")
public PriceVO get(@PathVariable Long eid, @AuthenticationPrincipal User user){
log.info("user is {}",user.getId());
// PriceVO forObject = restTemplate.getForObject("http://localhost:8080/price/" + id, PriceVO.class);
return new PriceVO();
}