OAuth2.0系列之密码模式实践教程(四)
@
OAuth2.0系列博客:
- OAuth2.0系列之基本概念和运作流程(一)
- OAuth2.0系列之授权码模式实践教程(二)
- OAuth2.0系列之简化模式实践教程(三)
- OAuth2.0系列之密码模式实践教程(四)
- OAuth2.0系列之客户端模式实践教程(五)
- OAuth2.0系列之集成JWT实现单点登录
1、密码模式简介
1.1 前言简介
在上一篇文章中我们学习了OAuth2的一些基本概念,对OAuth2有了基本的认识,接着学习OAuth2.0授权模式中的密码模式
ps:OAuth2.0的授权模式可以分为:
- 授权码模式(authorization code)
- 简化模式(implicit)
- 密码模式(resource owner password credentials)
- 客户端模式(client credentials)
密码模式(resource owner password credentials):密码模式中,用户向客户端提供自己的用户名和密码,这通常用在用户对客户端高度信任的情况
1.2 授权流程图
官网图片:

- (A)用户访问客户端,提供URI连接包含用户名和密码信息给授权服务器
- (B)授权服务器对客户端进行身份验证
- (C)授权通过,返回acceptToken给客户端
从调接口方面,简单来说:
- 第一步:直接传username,password获取token
- 第二步:拿到acceptToken之后,就可以直接访问资源
http://localhost:8084/api/userinfo?access_token=${accept_token}
2、例子实践
2.1 实验环境准备
- IntelliJ IDEA
- Maven3.+版本
新建SpringBoot Initializer项目,可以命名password


主要是想引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Oauth2-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<!-- Spring Cloud Security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
2.2 OAuth2.0角色
前面的学习,我们知道了OAuth2.0主要包括如下角色,下面通过代码例子加深对理论的理解
- 资源所有者(Resource Owner)
- 用户代理(User Agent)
- 客户端(Client)
- 授权服务器(Authorization Server)
- 资源服务器(Resource Server)
生产环境、资源服务器和授权服务器一般是分开的,不过学习的可以放在一起
定义资源服务器,用注解@EnableResourceServer;
定义授权服务器,用注解@EnableAuthorizationServer;
2.3 OAuth2.0配置类
package com.example.oauth2.password.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* <pre>
* OAuth2.0配置类
* </pre>
*
* <pre>
* @author mazq
* 修改记录
* 修改后版本: 修改人: 修改日期: 2020/06/11 11:00 修改内容:
* </pre>
*/
@Configuration
//开启授权服务
@EnableAuthorizationServer
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
private static final String CLIENT_ID = "cms";
private static final String SECRET_CHAR_SEQUENCE = "{noop}secret";
private static final String SCOPE_READ = "read";
private static final String SCOPE_WRITE = "write";
private static final String TRUST = "trust";
private static final String USER ="user";
private static final String ALL = "all";
private static final int ACCESS_TOKEN_VALIDITY_SECONDS = 2*60;
private static final int FREFRESH_TOKEN_VALIDITY_SECONDS = 2*60;
// 密码模式授权模式
private static final String GRANT_TYPE_PASSWORD = "password";
//授权码模式
private static final String AUTHORIZATION_CODE = "authorization_code";
//refresh token模式
private static final String REFRESH_TOKEN = "refresh_token";
//简化授权模式
private static final String IMPLICIT = "implicit";
//指定哪些资源是需要授权验证的
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
// 使用内存存储
.inMemory()
//标记客户端id
.withClient(CLIENT_ID)
//客户端安全码
.secret(SECRET_CHAR_SEQUENCE)
//为true 直接自动授权成功返回code
.autoApprove(true)
.redirectUris("http://127.0.0.1:8084/cms/login") //重定向uri
//允许授权范围
.scopes(ALL)
//token 时间秒
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS)
//刷新token 时间 秒
.refreshTokenValiditySeconds(FREFRESH_TOKEN_VALIDITY_SECONDS)
//允许授权类型
.authorizedGrantTypes(GRANT_TYPE_PASSWORD );
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 使用内存保存生成的token
endpoints.authenticationManager(authenticationManager).tokenStore(memoryTokenStore());
}
/**
* 认证服务器的安全配置
*
* @param security
* @throws Exception
*/
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
//.realm(RESOURCE_ID)
// 开启/oauth/token_key验证端口认证权限访问
.tokenKeyAccess("isAuthenticated()")
// 开启/oauth/check_token验证端口认证权限访问
.checkTokenAccess("isAuthenticated()")
//允许表单认证
.allowFormAuthenticationForClients();
}
@Bean
public TokenStore memoryTokenStore() {
// 最基本的InMemoryTokenStore生成token
return new InMemoryTokenStore();
}
}
2.4 Security配置类
为了测试,可以进行简单的SpringSecurity
package com.example.oauth2.password.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* <pre>
* SpringSecurity配置类
* </pre>
*
* <pre>
* @author mazq
* 修改记录
* 修改后版本: 修改人: 修改日期: 2020/06/11 11:23 修改内容:
* </pre>
*/
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { //auth.inMemoryAuthentication()
auth.inMemoryAuthentication()
.withUser("nicky")
.password("{noop}123")
.roles("admin");
}
@Override
public void configure(WebSecurity web) throws Exception {
//解决静态资源被拦截的问题
web.ignoring().antMatchers("/asserts/**");
web.ignoring().antMatchers("/favicon.ico");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http // 配置登录页并允许访问
//.formLogin().permitAll()
// 配置Basic登录
//.and().httpBasic()
// 配置登出页面
.logout().logoutUrl("/logout").logoutSuccessUrl("/")
// 配置允许访问的链接
.and().authorizeRequests().antMatchers("/oauth/**", "/login/**", "/logout/**","/api/**").permitAll()
// 其余所有请求全部需要鉴权认证
.anyRequest().authenticated()
// 关闭跨域保护;
.and().csrf().disable();
}
}
2.5 功能简单测试
接口测试,要用POST方式,在postman测试,response_type参数传password:
http://localhost:8888/oauth/token?password=123&grant_type=password&username=nicky&scope=all

注意配置一下请求头的授权参数,username即client_id,password即client_secret

代码方式请求,可以进行如下封装,即进行base64加密
HttpHeaders headers = new HttpHeaders();
byte[] key = (clientId+":"+clientSecret).getBytes();
String authKey = new String(Base64.encodeBase64(key));
LOG.info("Authorization:{}","Basic "+authKey);
headers.add("Authorization","Basic "+authKey);
拿到token直接去调业务接口:
http://localhost:8888/api/userinfo?access_token=61b113f3-f1e2-473e-a6d7-a0264bfdfa8d
例子代码下载:code download
OAuth2.0系列之密码模式实践教程(四)的更多相关文章
- OAuth2.0系列之基本概念和运作流程(一)
@ 目录 一.OAuth2.0是什么? 1.1 OAuth2.0简介 1.2 OAuth2.0官方文档 二.OAuth2.0原理 2.1 OAuth2.0流程图 三. OAuth2.0的角色 四.OA ...
- SpringBoot系列之自定义starter实践教程
SpringBoot系列之自定义starter实践教程 Springboot是有提供了很多starter的,starter翻译过来可以理解为场景启动器,所谓场景启动器配置了自动配置等等对应业务模块的一 ...
- Oauth2.0认证---授权码模式
目录: 1.功能描述 2.客户端的授权模式 3.授权模式认证流程 4.代码实现 1.功能描述 OAuth在"客户端"与"服务提供商"之间,设置了一个授权层(au ...
- 被广泛使用的OAuth2.0的密码模式已经废了,放弃吧
最近一直有同学在问,OAuth2密码模式为啥Spring Security还没有实现,就连新的Spring Authorization Server也没有这个玩意儿. 其实这里可以告诉大家,OAuth ...
- OAuth2.0 四种授权模式
OAuth2.0简单笔记(四种授权模式) 金天:坚持写东西,不是一件容易的事,换句话说其实坚持本身都不是一件容易的事.如果学习有捷径,那就是不断实践,不断积累.写笔记,其实是给自己看的,是体现积累的一 ...
- Spring Boot Security Oauth2之客户端模式及密码模式实现
Spring Boot Security Oauth2之客户端模式及密码模式实现 示例主要内容 1.多认证模式(密码模式.客户端模式) 2.token存到redis支持 3.资源保护 4.密码模式用户 ...
- IdentityServer4实现Oauth2.0四种模式之隐藏模式
接上一篇:IdentityServer4实现OAuth2.0四种模式之密码模式,密码模式将用户的密码暴露给了客户端,这无疑是不安全的,隐藏模式可以解决这个问题,由用户自己在IdentityServ ...
- IdentityServer4系列 | 授权码模式
一.前言 在上一篇关于简化模式中,通过客户端以浏览器的形式请求IdentityServer服务获取访问令牌,从而请求获取受保护的资源,但由于token携带在url中,安全性方面不能保证.因此,我们可以 ...
- OAuth2.0 知多少
1. 引言 周末逛简书,看了一篇写的极好的文章,点击大红心点赞,就直接给我跳转到登录界面了,原来点赞是需要登录的. 可是没有我并没有简书账号,一直使用的QQ的集成登录.下面有一排社交登录按钮,我们可以 ...
- ASP.NET WebApi 基于OAuth2.0实现Token签名认证
一.课程介绍 明人不说暗话,跟着阿笨一起玩WebApi!开发提供数据的WebApi服务,最重要的是数据的安全性.那么对于我们来说,如何确保数据的安全将是我们需要思考的问题.为了保护我们的WebApi数 ...
随机推荐
- 远程服务器(腾讯云轻量服务器)上安装SQL Server以及SQL Server Management Studio,以及EFCore对其的连接
SQL Server的安装 下载地址:https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 安装教程参考:https://bl ...
- Python单元测试标准库unittest简单学习
1.背景 当需要测试较为复杂的module,class或者系统的功能时,如果一个一个的去测试就会显得很麻烦,如果每项测试又有一定的配置或者设置的话,比如每个测试都要新建一个对象之类的,那就更麻烦了.单 ...
- MySQL 添加和删除索引
摘要:介绍添加.删除和显示索引的方法. 今天为大家演示MySQL数据库索引的常见操作,包括创建.删除和查询等.下面首先介绍为什么需要添加索引. 索引的作用 索引用于快速找出在某一列中有一特定值 ...
- C# 锁机制全景与高效实践:从 Monitor 到 .NET 9 全新 Lock
引言:线程安全与锁的基本概念 线程安全 在多线程编程中,保障共享资源的安全访问依赖于有效的线程同步机制.理解并处理好以下两个核心概念至关重要: 线程安全:指某个类.方法或数据结构能够在被多个线程同时访 ...
- Go 进阶训练营 Week02: error 错误处理
Error vs Exception Error: Go error 就是普通的一个接口,普通的值.Errors are values type error interface { Error() s ...
- gitlab跨版本升级
此文档只讲述基于Omnibus 包安装的GitLab 修复示例: 本文采用升级gitlab版本来修复漏洞.因为gitlab官方会定期发行新版本用于修复漏洞 此升级为跨版本升级(14.10.x-ee - ...
- Kong入门学习实践(8)流量控制插件
Kong的一大特色就在于强大的可扩展性,具体实现方式就是插件.一来Kong已经提供了很多内置的插件,二来我们也可以使用Lua语言自定义开发插件.今天,我们就来了解一些常用的流量控制插件. 关于流量控制 ...
- Vue 中可以定义组件模版的几种方式
前置知识回顾 new Vue({...options})一些基本知识 new Vue(options)的选项中,也可以拥有 data.methods.components.生命周期函数等等,和组件实例 ...
- 用java的眼光看js的oop
前言 都知道javascript的class只是语法糖而已,所以没法去对比,不在一个层次. 但是既然有了,总会有好奇的去对比. 那就对比一下. 面向对象的三个经典特性 封装 继承 多态 封装 指的是将 ...
- A - Ability Draft Gym - 102155A 状压DP
传送门 题意:有两个队伍,每队有n个人,每个人可以有s个普通技能和一个特殊技能.现在可以按照顺序抽技能卡,问各自都在最优策略下双方队伍的技能总分最大差值. 思路:算是一道看着简单但思路形成比较麻烦的一 ...