如果不了解Oauth2 是什么、工作流程的可以看我上一篇文章:

SpringCloud-OAuth2(一):基础篇

这篇讲的内容是:Oauth2在SpringBoot/SpringCloud中的实战。

SpringBoot版本:2.2.5.Release

SpringCloud版本:Hoxton.SR9

JDK版本:1.8

1:POM配置

    <dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
<dependency>
<artifactId>spring-cloud-starter-oauth2</artifactId>
<groupId>org.springframework.cloud</groupId>
</dependency>
<!--使用redis存放token-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--密码加密解密依赖包-->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>

2:关键配置

2.1:认证服务配置-WebAuthorizationConfig

@Configuration
@EnableAuthorizationServer
public class WebAuthorizationConfig extends AuthorizationServerConfigurerAdapter { private final AuthenticationManager authenticationManager;
private final UserDetailsService userDetailsService;
private final PasswordEncoder passwordEncoder;
private final TokenStore tokenStore;
private final AuthorizationCodeServices authorizationCodeServices;
private final AuthTokenExceptionHandler authTokenExceptionHandler; public WebAuthorizationConfig(AuthenticationManager authenticationManager,
UserDetailsService userDetailsService,
PasswordEncoder passwordEncoder,
TokenStore tokenStore,
AuthorizationCodeServices authorizationCodeServices,
AuthTokenExceptionHandler authTokenExceptionHandler) {
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.passwordEncoder = passwordEncoder;
this.tokenStore = tokenStore;
this.authorizationCodeServices = authorizationCodeServices;
this.authTokenExceptionHandler = authTokenExceptionHandler;
} @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secret = PasswordHelper.encryptPassword(Oauth2ClientUserEnums.ADMIN.getClientSecret()); clients.inMemory()
.withClient(Oauth2ClientUserEnums.ADMIN.getClientId())
.secret(secret)
.scopes("all", "test")
.resourceIds("admin")
// autoApprove 可跳过授权页直接返回code
.autoApprove("all")
.redirectUris("http://www.baidu.com")
//客户端认证所支持的授权类型 1:客户端凭证 2:账号密码 3:授权码 4:token刷新 5:简易模式
.authorizedGrantTypes(CLIENT_CREDENTIALS, PASSWORD, REFRESH_TOKEN, AUTHORIZATION_CODE, IMPLICIT)
//用户角色
.authorities("admin")
//允许自动授权
.autoApprove(false)
//token 过期时间
.accessTokenValiditySeconds((int) TimeUnit.HOURS.toSeconds(12))
//refresh_token 过期时间
.refreshTokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(30))
;
} @Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.passwordEncoder(passwordEncoder) //设置密码编辑器
.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()") //开启 /oauth/token_key 的访问权限控制
.checkTokenAccess("permitAll()") //开启 /oauth/check_token 验证端口认证权限访问
;
} @Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 配置授权服务器端点的属性
endpoints.authenticationManager(authenticationManager) //认证管理器
.tokenStore(tokenStore)
.authorizationCodeServices(authorizationCodeServices)
.userDetailsService(userDetailsService)
.exceptionTranslator(authTokenExceptionHandler);
}
}

注解:@EnableAuthorizationServer表明当前服务是认证服务。


介绍一下几个基础组件


①:authenticationManager

认证管理器,对客户端凭证、用户进行认证的地方。


②:tokenStore

存放token的地方,默认是存放在Inmemory(内存)中的。


③:authorizationCodeServices

code生成服务,使用默认的即可。


④:userDetailsService

用户详情服务,可重写实现,用户信息从数据库中加载。


⑤:authTokenExceptionHandler

自定义的 token 鉴别失败异常处理器。


⑥:authClientExceptionHandler

自定义的 客户端凭证 鉴别失败异常处理器。

2.2:资源服务配置-WebResourceConfig

@Configuration
@EnableResourceServer
public class WebResourceConfig extends ResourceServerConfigurerAdapter { private final AuthClientExceptionHandler authClientExceptionHandler; public WebResourceConfig(AuthClientExceptionHandler authClientExceptionHandler) {
this.authClientExceptionHandler = authClientExceptionHandler;
} @Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId("admin").stateless(true).authenticationEntryPoint(authClientExceptionHandler);
} @Override
public void configure(HttpSecurity http) throws Exception {
// 资源链路
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().formLogin().permitAll()
// 登录放通
.and()
.authorizeRequests()
.antMatchers("/oauth/**", "/favicon.ico")
//.authenticated()
.permitAll()
// 其他请求都需认证
.and()
.authorizeRequests()
.anyRequest()
.authenticated()
// 跨域
.and()
.cors()
// 关闭跨站请求防护
.and()
.csrf()
.disable();
} }

注解:@EnableResourceServer表明当前服务是认证服务。

笔记:

为什么要放开 /favicon.ico 的访问权限?因为在进行授权码模式的时候,一直无法跳转到我定义的redirect_uri 地址中去。

使用 logging.level.org.springframework.security=debug 发现会访问 /favicon.ico ,然后报错,再然后就是调到登录页去了。

因此 /favicon.ico 放开之后,认证正常,成功调到redirect_uri 地址并返回了code。(这是OAuth2的小坑吗?)

2.3:安全配置-WebSecurityConfig

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final PasswordEncoder passwordEncoder; public WebSecurityConfig(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
} @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder); //为认证管理器配置passwordEncoder,无论客户端凭证密码还是用户密码都通过passwordEncoder进行密码匹配
} @Bean
@Override
protected UserDetailsService userDetailsService() {
return new VipUserDetailService();
} @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
} }

详细配置可以翻阅我的GitHub:GitHub地址

3:认证授权演示

3.1:授权码模式

注意!!!一定要配置redirect_uri,并且一定要允许表单登录!!!

以下是步骤:


①:浏览器输入以下链接地址,会重定向到登录页

http://localhost:8123/oauth/authorize?client_id=admin&client_secret=admin&response_type=code&redirect_uri=http://www.baidu.com&scope=test


②:输入配置的用户名密码,回调到授权页

如果我们配置的scope是autoApprove的,即可跳过这步,直接到第③步,拿到code。


③:选择 Approve,点击Authorize 即可调到redirect_uri地址


④:拿code 换 token

我的请求地址:127.0.0.1:8123/oauth/token?grant_type=authorization_code&code=h35Fh1&redirect_uri=http://www.baidu.com

需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.2:用户密码模式

我的请求地址:127.0.0.1:8123/oauth/token?grant_type=password&username=found&password=123456

需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.3:客户端凭证模式

我的请求地址:127.0.0.1:8123/oauth/token?grant_type=client_credentials

需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

3.4:简易模式

浏览器输入以下地址即可拿到token:

http://localhost:8123/oauth/authorize?client_id=admin&client_secret=admin&response_type=token&redirect_uri=http://www.baidu.com

3.5:token 刷新

我的请求地址:127.0.0.1:8123/oauth/token?grant_type=refresh_token&refresh_token=dde5f388-4ad7-4781-a1b7-aaafb3c34b10

refresh_token是服务器颁发给客户端的,作用就是在一定时间内,让用户不用重新登录。

需要配置Authorization,请求时会将客户端凭证以base64格式放在请求头中。

4:从第三方登录让你理解什么是授权码模式

个人认为做第三方登录是当前比较流行的做法。

4.1:流程

①:比如我们现在登录processOn,就可以选择第三方登录。


②:点击QQ登录后会调到这个页面↓↓↓↓↓↓↓↓↓↓↓↓


③:这个client_id 应该就是processOn 官方申请的第三方客户端凭证了。

选择账号密码登录,输入账号密码之后就可以拿到token,(我手速快截了个图)


④:可以看到返回了access_token、过期时间。

随后processOn既发起请求进行登录操作,登录成功进入用户首页,失败则重定向到登录页。



4.2:uml图

可以看到不需要用户进行Authorize操作即可拿到token了,说明QQ第三方认证中心设置的scope=all是autoApprove的。

总结 :

学习总要从身边找例子,这样才能更好的理解。

最新文章

  1. MySQL replace into 使用详解 及 注意事项
  2. hdoj 5139Formula
  3. 算法:寻找maximum subarray
  4. Socket Server-基于NIO的TCP服务器
  5. [c#]一个窗体调用另一个窗体的事件
  6. VMware Workstation虚拟机中的Linux通过NAT模式共享上网配置教程
  7. apache无法正常启动,80端口被占用的解决方法
  8. (转载)自定义 setDateFormat 显示格式
  9. Android四大组件之——Activity的生命周期(图文详解)
  10. How to Read a Book
  11. spring4 文件下载功能
  12. 打开开源项目总得.md文件
  13. (原创)jquery插件-可选可填控件
  14. 常用sqlserver语句
  15. c++ const char *c_str(); 坑的学习
  16. 信用卡/借记卡充值p2p平台
  17. PyQt4--QPushButton阵列
  18. c++, 虚基派生 : 共同基类产生的二义性的解决办法
  19. [python标准库]Pickle模块
  20. [bzoj4874]筐子放球

热门文章

  1. [CSP-J2019 江西] 道路拆除 题解
  2. thymeleaf中[[${}]]与[(${})]的区别
  3. 在 Linux 如何优雅的统计程序运行时间?恕我直言,你运行的可能是假 time
  4. JS实现单例模式的多种方案
  5. 腾讯云原生混合云-第三方集群弹EKS应对突发流量的利器
  6. CRM客户关系管理系统有哪些优缺点?
  7. [bug] JavaScript:Uncaught SyntaxError: missing ) after argument list
  8. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)
  9. Linux 系统定时任务:crontab,anacron
  10. IDEA Git 操作常见错误处理