Spring Security OAuth2 授权码模式的实现
写在前边
在文章OAuth2.0概念及授权流程梳理中我们谈到OAuth2.0的概念与流程,这里我准备分别记一记这几种授权模式的demo,一方面为自己的最近的学习做个总结,另一方面做下知识输出,如果文中有错误的地方,请评论指正,在此不胜感激
受众前提
阅读本文,默认读者已经过SpringSecurity有一定的了解,对OAuth2流程有一定了解
本文目标
带领读者对SpringSecurityOAuth2框架的授权码模式有一个比较直观的概念,能使用框架搭建授权码模式授权服务器与资源服务器(分离版本)
授权码模式流程回顾
授权码模式要求:用户登录并对第三方应用(客户端)进行授权,出示授权码交给客户端,客户端凭授权码换取access_token(访问凭证)
此模式要求授权服务器与用户直接交互,在此过程中,第三方应用是无法获取到用户输入的密码等信息的,这个模式也是OAuth2.0中最安全的一个
Demo基本结构
这里主要关注authorization-code-authorization-server与authorization-code-resource-server这两个模块
本文以及后续文章的demo均放在GitHub上,欢迎大家Star&Fork,源码地址:https://github.com/hellxz/spring-security-oauth2-learn
authorization-code-client-resttemplate-jdbc这个项目是用来测试非OAuth2服务使用RestTemplate与JdbcTemplate对接OAuth2授权服务的,流程这里不讲,有兴趣可以debug看看,可能会让您对整个流程会有更清晰的感受
Maven依赖
org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-web org.springframework.security.oauth spring-security-oauth2 ${spring-security-oauth2.version}
搭建授权服务器(AuthorizationServer)
文中服务器均使用demo级别配置,请勿直接使用到生产环境
授权服务器结构主体如下:
启动类自不多说,先说下SecurityConfig
packagecom.github.hellxz.oauth2.config; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; importorg.springframework.security.config.annotation.web.builders.HttpSecurity; importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity; importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; importorg.springframework.security.crypto.password.PasswordEncoder; importjava.util.Collections; @Configuration @EnableWebSecurity publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{ @Bean publicPasswordEncoderpasswordEncoder(){ returnnewBCryptPasswordEncoder(); } @Override protectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{ //@formatter:off auth.inMemoryAuthentication() .withUser("hellxz") .password(passwordEncoder().encode("xyz")) .authorities(Collections.emptyList()); //@formatter:on } @Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http.authorizeRequests() .anyRequest().authenticated()//所有请求都需要通过认证 .and() .httpBasic()//Basic登录 .and() .csrf().disable();//关跨域保护 } }
通过@Configuration和@EnableWebSecurity开启SpringSecurity配置,继承WebSecurityConfigurerAdapter的方法,实现个性化配置,这里我们使用内存保存一个名为hellxz、密码为xyz的用户,与授权服务器交互的用户就是他了
除了配置用户,我们需要对服务的资源进行保护,这里将所有的请求都要求通过认证才可以访问,用户登录需要使用httpBasic形式(就是那种网页弹个窗要求登录的那种