要实现OAuth服务端,就得先理解客户端的调用流程,服务提供商实现可能也有些区别,实现OAuth服务端的方式很多,具体可能看 http://oauth.net/code/

各语言的实现有(我使用了Apache Oltu):

实现主要涉及参数配置如下:
授权码设置(code)
第三方通过code进行获取 access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。
授权作用域(scope)
作用域代表用户授权给第三方的接口权限,第三方应用需要向服务端申请使用相应scope的权限后,经过用户授权,获取到相应access_token后方可对接口进行调用。
令牌有效期(access_token)
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
    1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
    2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

项目介绍

项目结构如下:
AuthzController:获取授权码
TokenController:获得令牌
ResourceController:资源服务
ClientController:客户端

基础代码放到github:https://github.com/zhouyongtao/homeinns-web

确保项目8080端口运行,可以手动调试

获得授权码
http://localhost:8080/oauth2/authorize?client_id=fbed1d1b4b1449daa4bc49397cbe2350&response_type=code&redirect_uri=http://localhost:8080/oauth_callback
获得令牌(POST)
http://localhost:8080/oauth2/access_token?client_id=fbed1d1b4b1449daa4bc49397cbe2350&client_secret=fbed1d1b4b1449daa4bc49397cbe2350&grant_type=authorization_code&redirect_uri=http://localhost:8080/oauth_callback&code={code}

客户端

也可以使用如下客户端测试代码,访问 http://localhost:8080/client 测试

/**
* Created by Irving on 2014/11/24.
* OAuth2 客户端实现
*/
@Controller
@RequestMapping("/client")
public class ClientController { private static Logger logger = LoggerFactory.getLogger(ClientController.class);
/*
response_type:表示授权类型,必选项,此处的值固定为"code"
client_id:表示客户端的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值
*/
/**
* 获得授权码
* @return
*/
@RequestMapping(method = RequestMethod.GET)
public String client() {
try {
OAuthClientRequest oauthResponse = OAuthClientRequest
.authorizationLocation(ConstantKey.OAUTH_CLIENT_AUTHORIZE)
.setResponseType(OAuth.OAUTH_CODE)
.setClientId(ConstantKey.OAUTH_CLIENT_ID)
.setRedirectURI(ConstantKey.OAUTH_CLIENT_CALLBACK)
.setScope(ConstantKey.OAUTH_CLIENT_SCOPE)
.buildQueryMessage();
return "redirect:"+oauthResponse.getLocationUri();
} catch (OAuthSystemException e) {
e.printStackTrace();
}
return "redirect:/home";
} /*
grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"
code:表示上一步获得的授权码,必选项。
redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致
client_id:表示客户端ID,必选项
*/
/**
* 获得令牌
* @return oauth_callback?code=1234
*/
@RequestMapping(value = "/oauth_callback" ,method = RequestMethod.GET)
public String getToken(HttpServletRequest request,Model model) throws OAuthProblemException {
OAuthAuthzResponse oauthAuthzResponse = null;
try {
oauthAuthzResponse = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
String code = oauthAuthzResponse.getCode();
OAuthClientRequest oauthClientRequest = OAuthClientRequest
.tokenLocation(ConstantKey.OAUTH_CLIENT_ACCESS_TOKEN)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(ConstantKey.OAUTH_CLIENT_ID)
.setClientSecret(ConstantKey.OAUTH_CLIENT_SECRET)
.setRedirectURI(ConstantKey.OAUTH_CLIENT_CALLBACK)
.setCode(code)
.buildQueryMessage();
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient()); //Facebook is not fully compatible with OAuth 2.0 draft 10, access token response is
//application/x-www-form-urlencoded, not json encoded so we use dedicated response class for that
//Custom response classes are an easy way to deal with oauth providers that introduce modifications to
//OAuth 2.0 specification //获取access token
OAuthJSONAccessTokenResponse oAuthResponse = oAuthClient.accessToken(oauthClientRequest, OAuth.HttpMethod.POST);
String accessToken = oAuthResponse.getAccessToken();
String refreshToken= oAuthResponse.getRefreshToken();
Long expiresIn = oAuthResponse.getExpiresIn();
//获得资源服务
OAuthClientRequest bearerClientRequest = new OAuthBearerClientRequest(ConstantKey.OAUTH_CLIENT_GET_RESOURCE)
.setAccessToken(accessToken).buildQueryMessage();
OAuthResourceResponse resourceResponse = oAuthClient.resource(bearerClientRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
String resBody = resourceResponse.getBody();
logger.info("accessToken: "+accessToken +" refreshToken: "+refreshToken +" expiresIn: "+expiresIn +" resBody: "+resBody);
model.addAttribute("accessToken", "accessToken: "+accessToken + " resBody: "+resBody);
return "oauth2/token";
} catch (OAuthSystemException ex) {
logger.error("getToken OAuthSystemException : " + ex.getMessage());
model.addAttribute("errorMsg", ex.getMessage());
return "/oauth2/error";
}
}
}

Refer:
https://cwiki.apache.org/confluence/display/OLTU/Index

https://open.weixin.qq.com/cgi-bin/readtemplate?t=resource/app_wx_login_tmpl&lang=zh_CN#faq

Apache Oltu 实现 OAuth2.0 服务端【授权码模式(Authorization Code)】的更多相关文章

  1. 基于OWIN WebAPI 使用OAUTH2授权服务【授权码模式(Authorization Code)】

    之前已经简单实现了OAUTH2的授权码模式(Authorization Code),但是基于JAVA的,今天花了点时间调试了OWIN的实现,基本就把基于OWIN的OAUHT2的四种模式实现完了.官方推 ...

  2. IdentityServer4 (3) 授权码模式(Authorization Code)

    写在前面 1.源码(.Net Core 2.2) git地址:https://github.com/yizhaoxian/CoreIdentityServer4Demo.git 2.相关章节 2.1. ...

  3. 创建自己的OAuth2.0服务端(一)

    如果对OAuth2.0有任何的疑问,请先熟悉OAuth2.0基础的文章:http://www.cnblogs.com/alunchen/p/6956016.html 1. 前言 本篇文章时对 客户端的 ...

  4. oauth2.0服务端与客户端搭建

    oauth2.0服务端与客户端搭建 - 推酷 今天搭建了oauth2.0服务端与客户端.把搭建的过程记录一下.具体实现的功能是:client.ruanwenwu.cn的用户能够通过 server.ru ...

  5. OAuth 第三方登录授权码(authorization code)方式的小例子

    假如上面的网站A,可以通过GitHub账号登录: 下面以OAuth其中一种方式,授权码(authorization code)方式为例. 一.第三方登录的原理 所谓第三方登录,实质就是 OAuth 授 ...

  6. Java的oauth2.0 服务端与客户端的实现

    oauth原理简述 oauth本身不是技术,而是一项资源授权协议,重点是协议!Apache基金会提供了针对Java的oauth封装.我们做Java web项目想要实现oauth协议进行资源授权访问,直 ...

  7. 写个OAuth2.0的请求端来测试自己的OAuth2.0服务端(二)

    在上一篇文章中,我们介绍了怎么创建自己的服务器,现在我们开始写个client端,来测试. 我们创建一个MVC项目,叫TestOAuthClient 1. 代码开始 1)第一步,我们创建一个MainCo ...

  8. Kafka 1.1.0 服务端源码阅读笔记

    网络层 01: 服务器的启动 02: Acceptor和Processor 03: RequestChannel API层 04: Handler和Apis 06: Produce请求(1): 写入本 ...

  9. OAuth2.0 用户验证授权标准 理解

    OAuth2.0是一套标准. 一.问题 这个标准解决了这样的一个问题. 允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用.  ...

随机推荐

  1. 阿里ETL工具datax学习(一)

    阿里云开源离线同步工具DataX3.0介绍 一. DataX3.0概览 ​ DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.Ma ...

  2. 动态创建控件 #Create(...)

    在类中创建一个控件对象;例:CButton m_btn; 用Create创建一个对象(#其实已经与其绑定)m_btn.Create(.....); #注意Create()函数的参数 问题一:点击一个b ...

  3. ArcGIS 点云转DEM

  4. POJ3723--Conscription(MST)WRONG

    Description Windy has a country, and he wants to build an army to protect his country. He has picked ...

  5. noip第12课作业

    1.    输出低于班级平均分的学生信息 [问题描述] 输入N个学生的姓名和语文.数学的得分,求平均分低于班级平均分的学生,将其信息全部输出.分数相同的按输入先后输出. 输入格式:第1行,有一个整数N ...

  6. What mind mapping software applications do you recommend.

    选自 https://members.iqmatrix.co/creative-mind-maps I personally use Mindjet MindManager. This is one ...

  7. unigui 设置单元格颜色

    procedure TF_Resource2.UniDBGrid1DrawColumnCell(Sender: TObject; ACol,  ARow: Integer; Column: TUniD ...

  8. hdu 1.2.6

    勾股定理... #include<cstdio> #include<algorithm> using namespace std; int main() { //freopen ...

  9. python操作excel及json

    有一个存着学生成绩的文件:stuscore.txt,里面存的是json串,json串读起来特别不直观,需要你写代码把它都写到excel中,并计算出总分和平均分,json格式如下: { ":[ ...

  10. WebAPI中发送字节数组

    今天工作中遇到了一个情景: 前端向后台发送一个请求,希望后台返回一组数据,由于后台返回的数据量很大,希望尽可能压缩响应的大小 我的想法:后台将数据(Short的数组)直接转换成Byte[]  然后将b ...