美文网首页
Android常用OAuth登陆与分享

Android常用OAuth登陆与分享

作者: baolvlv | 来源:发表于2017-09-01 13:20 被阅读0次

    本文分两部分,第一部分介绍OAuth基础知识,第二部分展示一个Demo,使用百度OAuth SDK获取令牌信息与用户信息。

    详细代码:github.com/Baolvlv/LearnAndroid/tree/master/OAuthDemo

    一、OAuth基础知识

    1.OAuth概述与运行流程

    OAuth是关于授权(authorization)的开放的网络标准,用户允许第三方应用访问用户在某一网站上的私密资源,而不需将用户名与密码提供给第三方应用,通过OAuth访问可以限制第三方应用的范围和有效期。

    2006年11月,OpenID不能满足twitter的委托授权

    2007年4月,成立OAuth讨论小组

    2007年11月,OAuth核心1.0最后的草案发布

    2010年4月,OAuth1.0协议发布  RFC-5849

    2012年12月,OAuth2.0协议发布 RFC-6749

    OAuth 2.0不向下兼容OAuth 1.0

    +--------+                               +---------------+

    |        |--(A)- Authorization Request ->|   Resource    |

    |        |                               |     Owner     |

    |        |<-(B)-- Authorization Grant ---|               |

    |        |                               +---------------+

    |        |

    |        |                               +---------------+

    |        |--(C)-- Authorization Grant -->| Authorization |

    | Client |                               |     Server    |

    |第三方应用 |<-(D)----- Access Token ———|  授权服务器       |

    |        |            (令牌)            +---------------+

    |        |

    |        |                               +---------------+

    |        |--(E)----- Access Token ------>|    Resource   |

    |        |                               |     Server    |

    |        |<-(F)--- Protected Resource ---|               |

    +--------+                               +———————+

    2.OAuth授权模式

    1.授权码模式(Authorization Code)

    2.简化模式(implicit grant)

    3.密码模式(resource owner password credentials)

    4.客户端模式(client credentials)

    授权码模式最完整严密,下图为授权码模式流程

    +----------+

    | Resource |

    |   Owner  |

    |          |

    +----------+

    ^

    |

    (B)

    +----|-----+          Client Identifier      +---------------+

    |         -+----(A)-- & Redirection URI ---->|               |

    |  User-   |                                 | Authorization |

    |  Agent  -+----(B)-- User authenticates --->|     Server    |

    |          |                                 |               |

    用户代理   -+----(C)-- Authorization Code ---<|               |

    +-|----|---+                                 +---------------+

    |    |                                         ^      v

    (A)  (C)                                        |      |

    |    |                                         |      |

    ^    v                                         |      |

    +---------+                                      |      |

    |         |>---(D)-- Authorization Code ---------'      |

    |  Client |          & Redirection URI                  |

    |         |                                             |

    |         |<---(E)----- Access Token -------------------'

    +---------+       (w/ Optional Refresh Token)

    Note: The lines illustrating steps (A), (B), and (C) are broken into

    two parts as they pass through the user-agent.

    Figure 3: Authorization Code Flow

    Redirection URI———重定向URIOptional Refresh Token———刷新令牌

    客户端发起两次请求,第一次以获得临时授权码作为结束,第二次以获得令牌作为结束

    用户代理一般为浏览器

    第一次请求参数:

    第一次请求返回参数:


    第二次请求参数:


    请求方式:


    第二次请求需要客户端的ID与密钥

    现在普遍使用Https,当使用Https时,get和post请求安全性相同,get方式更加便捷。

    使用http+Basic时,使用post方式更为安全,请求信息不可以在url中直接读取,post会将请求内容隐藏到请求实体中。

    Content-Type:申请的表单类型

    grant_type:请求实体

    Http Basic Authentication:

    访问一个特定的域名或url时,需要通过用户名和密码进行授权查看

    发起请求时携带用户名和密码信息:

    post方式和get方式:


    代码实现:post方式:


    第二次请求返回参数:


    access_token:令牌,expires_in:令牌的有效时间段

    refresh_token:刷新令牌,令牌实效后获取新的授权码

    3.OAuth授权模式:简化模式,密码模式,客户端模式

    简化模式流程:


    没有后台服务器,或不能妥善保管第三方密钥情况下:

    web-Hosted Client Resource:内嵌到浏览器中的客户端模块

    User-Agent:用户代理,一般为浏览器

    开始请求部分与授权码模式相同,返回值为重定向url和令牌,认证服务器将令牌放置在url的哈希值部分(#后面的部分)一般认为是未知信息,转发到服务端哈希值会被忽略掉。

    web资源模块处理重定向url,返回给用户代理一个脚本用于解析,用户代理完成解析后,返回给客户端令牌信息。

    通常会将web-Hosted Client Resource部分内嵌到Client,直接截取收到的信息,提取令牌信息简化流程

    简化模式请求参数:


    简化模式请求与返回值:


    没有刷新令牌的原因:不能妥善保管第三方密钥,有刷新令牌降低安全性

    密码模式请求流程:


    用户需要将用户名与密码告诉客户端,但客户端不得存储密码

    用户对客户端足够的信任,认证服务器没有其他的认证方式可以选择时采用。

    密码模式请求参数:


    密码模式请求具体内容:


    密码模式请求返回值:


    密码模式请求返回值与授权码模式返回值类似

    客户端模式请求流程:

    用户在客户端注册,客户端提出请求,授权不明显


    客户端模式请求参数:


    客户端模式请求具体内容:


    客户端模式请求返回值:

    客户端模式的返回值与其他几种认证类型类似:


    4.OAuth更新令牌与相关问题:

    更新令牌的方法:

    1.重复一遍认证流程,用户手动输入用户名密码,发起请求认证

    2.使用refreshtoken获取一个新的令牌,即刷新令牌操作

    更新令牌参数:


    更新令牌具体请求过程:


    4.1授权码模式中请求参数state的作用:


    当多个用户发起请求时,如果没有state参数,认证服务器只会返回临时授权码这一个参数,容易混淆。添加state参数可以将发起请求的的用户与获得的临时授权码一一对应。对应方式不可预期以提高安全性。

    4.2为什么需要临时授权这一过程:

    (1)redirect_url的安全性

    redirect_url由第三方提供,是一个可访问的server表单地址。如果被截获,令牌会被截获

    (2)redirect_url不如access token敏感,被截获不会泄漏用户的资源信息。

    (3)如果没有临时授权码这一步,需要增加整个认证过程中的安全性

    4.3 申请百度开发者账号以及百度OAuth

    http://developer.baidu.com/wiki/index.php?title=docs/oauth

    4.4获取百度令牌

    http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization

    4.5获取百度用户信息


    二、android工程中获取百度令牌信息

    http://developer.baidu.com/wiki/index.php?title=docs/oauth/showcase

    下载安卓相关的sdk,解压后将其中的 jar包导入工程。

    Project Structure->添加app的dependencies,添加百度相关的jar包

    创建Baidu对象,调用authorize方法,第四个参数新建百度对话框监听器对象,实现其完成,异常,错误,取消四个方法.

    //第一个参数为clientId,即API Key

    finalBaidu baidu =newBaidu("PRheS6ajilCjg1muyFDGeCYz",this);

    baidu.authorize(this, true, true, newBaiduDialog.BaiduDialogListener() {

    @Override

    public voidonComplete(Bundle bundle) {

    //获取baidu对象中的AccessToken

    refreshUI(baidu.getAccessToken());

    }

    @Override

    public voidonBaiduException(BaiduException e) {

    refreshUI("exception");

    }

    @Override

    public voidonError(BaiduDialogError baiduDialogError) {

    refreshUI("error");

    }

    @Override

    public voidonCancel() {

    refreshUI("cancel");

    }

    });

    在主线程中,创建私有方法,用以刷新ui

    private voidrefreshUI(finalString msg){

    runOnUiThread(newRunnable() {

    @Override

    public voidrun() {

    tvAccessToken.setText(msg);

    }

    内部类中只能调用外部类的final对象

    三、android工程中获取百度个人信息

    由于网络请求不能放在主线程中,所以通过以下两种方式实现:

    1.在主线程中新建线程,使用百度提供的api,调用Baidu的对象的request方法返回json文本

    启动线程

    newThread(){

    @Override

    public voidrun() {

    String url="https://openapi.baidu.com/rest/2.0/passport/users/getInfo";

    try{

    //使用baidu对象request时,第二个参数会自动将包含在对象中的access Token传入

    finalString jsonText =mBaidu.request(url,null,"GET");

    //返回对象为简单类(实体时)时,使用class型

    finalUserEntity user =mGson.fromJson(jsonText,UserEntity.class);

    //返回对象为泛型时,使用Type方式

    finalUserEntity user =mGson.fromJson(jsonText,newTypeToken(){}.getType());

    //在主线程中实现runnable接口,完成ui的更新

    runOnUiThread(newRunnable() {

    @Override

    public voidrun() {

    tvResult.setText(jsonText);

    tvUser.setText(mGson.toJson(user));

    }

    });

    }catch(IOException e) {

    e.printStackTrace();

    }catch(BaiduException e) {

    e.printStackTrace();

    }

    super.run();

    }

    }.start();

    其中通过使用Gson库,完成json文本到json实体的转换或json实体到json文本的转换

    首先实体化Gson对象

    mGson=newGson();

    相关文章

      网友评论

          本文标题:Android常用OAuth登陆与分享

          本文链接:https://www.haomeiwen.com/subject/pbnhjxtx.html