重点:


授权服务器如果同时存在WebSecurityConfigurerAdapter和ResourceServer,那么如下授权模式部分是无法使用的,所以保留WebSecurityConfigurerAdapter

 

假设具体参数如下:

 

(1)请求地址为:http://localhost:7010/uaa/oauth/XX

(2)数据库表oauth_client_details初始化插入数据如下:

         INSERT INTO `oauth_client_details`    VALUES  ('wx_takeout_client_id
','test_resource_id','
$2a$10$I28j9B0T/roapkMEqfIHguARt0GgLyXwC/DOnFwPpXuQ0xTkrd632',

                                                                              
      'user_info','authorization_code,refresh_token,implicit,password
','http://localhost:7010/store/home',

                                                                              
    
 'ROLE_ADMIN,ROLE_DEVICE,ROLE_VIDEO',3600,7200,'{\"systemInfo\":\"Atlas  System\"}','true');

       
也就是说,授权表中client_id为wx_takeout_client_id,密码(需要用BCryptPasswordEncoder生成)为‘wx_takeout_client_secret’,改客户授权类型支持以下讨论的四种类型;

(3)用户表数据:

    用户名:lixx

    密   码:dw123456

 

注意这里有点不同就是client_id和具体用户lixx,一个是授权给第三方认证的客户id和秘钥用于授权用的,一个是系统的用户;

授权中心其中后自动添加的几个授权端点:





OAuth 2.0定义了四种授权方式。

*
密码模式(resource owner password credentials)

*
授权码模式(authorization code)

*
简化模式(implicit)

*
客户端模式(client credentials)

密码模式(resource owner password credentials)

*
这种模式是最不推荐的,因为client可能存了用户密码

*
这种模式主要用来做遗留项目升级为oauth2的适配方案

*
当然如果client是自家的应用,也是可以

*
支持refresh token

请求流程如下:

使用client_id和client_secret以及用户名密码直接获取秘钥

 

请求地址: 
http://localhost:7010/uaa/oauth/token?grant_type=password&username=lixx&password=dw123456

<http://localhost:7010/uaa/oauth/token?grant_type=password&username=lixx&password=dw123456>

请求类型:POST    必须为POST方式

请求参数:(1)URL中携带的参数,grant_type必须为密码模式(password)

                (2) URL中携带的参数,系统用户名:lixx,用户密码:dw123456

                (3)
经过HttpBasic加密的client_id和client_secret,这里就是wx_takeout_client_id和wx_takeout_secret编码后的值

请求返回:

{

    "access_token": "e361c0cd-dfb9-494d-9908-3175592ae94f",

    "token_type": "bearer",

    "refresh_token": "897f9bf7-6a7b-4a18-bd0e-cfd2826915e5",

    "expires_in": 3451,

    "scope": "user_info"

}

 

postman测试截图:

        

其中的authorization字段是通过填写自动生成的:



发送请求后返回:

     

授权码模式(authorization code)

*
这种模式算是正宗的oauth2的授权模式

*
设计了auth code,通过这个code再获取token

*
支持refresh token

请求流程如下:

(1)使用client_id和client_secret换取授权码过程

使用浏览器请求地址并跳转才能做到(postman不能跳转重定向)

请求地址:
http://localhost:7010/uaa/oauth/authorize?response_type=code&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login

<http://localhost:7010/uaa/oauth/authorize?response_type=code&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login>

请求如下:

请求后跳转到自定义(或自带的授权登录页面):



登录之后重定向到给定的重定向URL(这时候重定向后的地址接收到对应的授权码):



(2)通过授权码换取令牌



授权码返回

{

    "access_token": "7217d700-463a-4e8d-ab52-246e152e8627",

    "token_type": "bearer",

    "refresh_token": "897f9bf7-6a7b-4a18-bd0e-cfd2826915e5",

    "expires_in": 3599,

    "scope": "user_info"

}

(3)刷新token



注意交换token必须用之前获取的refresh_toekn进行交换一个新的token

 

简化模式(implicit)

*
这种模式比授权码模式少了code环节,回调url直接携带token

*
这种模式的使用场景是基于浏览器的应用

*
这种模式基于安全性考虑,建议把token时效设置短一些

*
不支持refresh token

implicit模式(隐式模式)和授权码模式(authorization_code)访问差不多,相比之下,少了一步获取code的步骤,而是直接获取token

 

请求: 用浏览器(此时同授权码模式,浏览器能跳转到登录页面,postman不行)
http://localhost:7010/uaa/oauth/authorize?response_type=token&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login

<http://localhost:7010/uaa/oauth/authorize?response_type=token&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login>

参数:
response_type=token&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login

<http://localhost:7010/uaa/oauth/authorize?response_type=token&client_id=wx_takeout_client_id&redirect_uri=http://localhost:7010/uaa/login>
 此时直接指定需要token,不用于授权码模式,先获取授权码

跳转到登录页面,如果还没有登录情况下:



登录授权,直接获取token:



如果不同意授权,跳转到重定向uri,并且返回error错误信息;登陆成功之后再次访问,跳转到用户授权页面



客户端模式(client credentials)

*
这种模式直接根据client的id和密钥即可获取token,无需用户参与

*
这种模式比较合适消费api的后端服务,比如拉取一组用户信息等

*
不支持refresh token,主要是没有必要

请求流程:



请求方式:POST

请求参数:请求头添加上
client_id和client_secret的basic编码,请求提添加grant_type必须设置为client_credentials

f返回结果:accesstoken



前提是表里也添加了对应的授权模式:



小结

*
密码模式(resource owner password credentials)(为遗留系统设计)(支持refresh token)

*
授权码模式(authorization code)(正宗方式)(支持refresh token)

*
简化模式(implicit)(为web浏览器应用设计)(不支持refresh token)

*
客户端模式(client credentials)(为后台api服务消费者设计)(不支持refresh token)

      应用范围:

*
Authorization Code:用在服务端应用之间

*
Implicit:用在移动app或者web app(这些app是在用户的设备上的,如在手机上调起微信来进行认证授权)

*
Resource Owner Password Credentials(password):应用直接都是受信任的(都是由一家公司开发的,本例子使用)

*
Client Credentials:用在应用API访问。