Spring Cloud Security 为构建安全的SpringBoot应用提供了一系列解决方案,结合Oauth2可以实现单点登录、令牌中继、令牌交换等功能,本文将对其结合Oauth2入门使用进行详细介绍。
OAuth 2.0是用于授权的行业标准协议。OAuth 2.0为简化客户端开发提供了特定的授权流,包括Web应用、桌面应用、移动端应用等。
这里我们创建一个oauth2-server模块作为认证服务器来使用。
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 复制代码
server: port: 9401 spring: application: name: oauth2-service 复制代码
/** * Created by macro on 2019/9/30. */ @Service public class UserService implements UserDetailsService { private List<User> userList; @Autowired private PasswordEncoder passwordEncoder; @PostConstruct public void initData() { String password = passwordEncoder.encode("123456"); userList = new ArrayList<>(); userList.add(new User("macro", password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin"))); userList.add(new User("andy", password, AuthorityUtils.commaSeparatedStringToAuthorityList("client"))); userList.add(new User("mark", password, AuthorityUtils.commaSeparatedStringToAuthorityList("client"))); } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { List<User> findUserList = userList.stream().filter(user -> user.getUsername().equals(username)).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(findUserList)) { return findUserList.get(0); } else { throw new UsernameNotFoundException("用户名或密码错误"); } } } 复制代码
/** * 认证服务器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; @Autowired private AuthenticationManager authenticationManager; @Autowired private UserService userService; /** * 使用密码模式需要配置 */ @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints.authenticationManager(authenticationManager) .userDetailsService(userService); } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("admin")//配置client_id .secret(passwordEncoder.encode("admin123456"))//配置client_secret .accessTokenValiditySeconds(3600)//配置访问token的有效期 .refreshTokenValiditySeconds(864000)//配置刷新token的有效期 .redirectUris("http://www.baidu.com")//配置redirect_uri,用于授权成功后跳转 .scopes("all")//配置申请的权限范围 .authorizedGrantTypes("authorization_code","password");//配置grant_type,表示授权类型 } } 复制代码
/** * 资源服务器配置 * Created by macro on 2019/9/30. */ @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest() .authenticated() .and() .requestMatchers() .antMatchers("/user/**");//配置需要保护的资源路径 } } 复制代码
/** * SpringSecurity配置 * Created by macro on 2019/10/8. */ @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override public void configure(HttpSecurity http) throws Exception { http.csrf() .disable() .authorizeRequests() .antMatchers("/oauth/**", "/login/**", "/logout/**") .permitAll() .anyRequest() .authenticated() .and() .formLogin() .permitAll(); } } 复制代码
/** * Created by macro on 2019/9/30. */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/getCurrentUser") public Object getCurrentUser(Authentication authentication) { return authentication.getPrincipal(); } } 复制代码
https://www.baidu.com/?code=eTsADY&state=normal 复制代码
使用授权码请求该地址获取访问令牌: http://localhost:9401/oauth/token
使用Basic认证通过client_id和client_secret构造一个Authorization头信息;
使用密码请求该地址获取访问令牌: http://localhost:9401/oauth/token
使用Basic认证通过client_id和client_secret构造一个Authorization头信息;
springcloud-learning └── oauth2-server -- oauth2认证测试服务 复制代码