SpringCloud下OAuth2實現網關安全架構圖
添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
搭建認證服務器
認證服務器配置
OAuth2AuthServerConfig 代碼:
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthServerConfig extends AuthorizationServerConfigurerAdapter {
/**
* 認證管理器
*/
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
/**
* 傳入authenticationManager,authenticationManager負責校驗
* @param endpoints
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints.authenticationManager(authenticationManager);
}
/**
* 配置客戶端應用
* @param
* @throws Exception
*/
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("orderApp")
.secret(passwordEncoder.encode("123456"))
.scopes("read","write")
.accessTokenValiditySeconds(3600)
.resourceIds("order-server")// 代表資源服務器的id,頒發的token可以訪問哪些資源服務器
.authorizedGrantTypes("password")
.and()
.withClient("orderService")
.secret(passwordEncoder.encode("123456"))
.accessTokenValiditySeconds(3600)
.scopes("read")
.authorizedGrantTypes("password");
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
// 必須經過認證才能校驗token
security.checkTokenAccess("isAuthenticated()");
}
}
OAuth2WebSecurityConfig 配置
/**
* 繼承web安全配置類的適配器
* @EnableWebSecurity 讓安全配置生效
*/
@Configuration
@EnableWebSecurity
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
/**
* spring 提供的加密算法工具
* @return
*/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* AuthenticationManagerBuilder ,構建認證管理器
* @return
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService) //用userDetailsService獲取用戶信息
.passwordEncoder(passwordEncoder()); // 用passwordEncoder比對密碼
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
UserDetailsService配置
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
/*
* 從數據庫取用戶
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 這裏構建了一個用戶
return User.withUsername(username)
.password(passwordEncoder.encode("abc123"))
.authorities("ROLE_ADMIN")
.build();
}
}
測試認證服務器
請求頭裏面加HttpBasic的認證:
搭建資源服務器
配置過程:
- 讓我們的訂單服務知道自己是OAuth2協議的資源服務器
- 配置是什麼資源服務器
- 配置驗證token的認證服務器
配置資源服務器
添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
OAuth2ResourceServerConfig
/**
*@Description
*@Author Evan
*@Date 2020/2/25 22:17
* @EnableResourceServer OAuth2 資源服務器
*/
@Configuration
@EnableResourceServer
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("orderService");
}
}
OAuth2WebSecurityConfig
/**
* 配置驗證token
* @EnableWebSecurity 讓安全配置生效
*/
@Configuration
@EnableWebSecurity
public class OAuth2WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public ResourceServerTokenServices tokenServices () {
RemoteTokenServices tokenServices = new RemoteTokenServices();
tokenServices.setClientId("orderService");
tokenServices.setClientSecret("123456");
// 驗證token的服務
tokenServices.setCheckTokenEndpointUrl("http://localhost:9090/oauth/check_token");
return tokenServices;
}
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
OAuth2AuthenticationManager auth2AuthenticationManager = new OAuth2AuthenticationManager();
auth2AuthenticationManager.setTokenServices(tokenServices());
return super.authenticationManager();
}
}
OrderController
@RestController
@RequestMapping("/orders")
@Slf4j
public class OrderController {
@PostMapping
public OrderInfo create(@RequestBody OrderInfo info, @AuthenticationPrincipal String username) {
log.info("user is " + username);
return info;
}
@GetMapping("/{id}")
public OrderInfo getInfo(@PathVariable Long id,@AuthenticationPrincipal String username) {
log.info("user is " + username);
log.info("orderId is " + id);
return new OrderInfo();
}
}