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();
}
}