最近因为公司的一个单点登录的需求,需要用到OAuth2.0协议,所以研究了一下OAuth2.0协议。
OAuth2.0十一中用于用户身份认证和授权的协议。
下面是摘自百度百科,供参考:
OAuth is a security protocol that enables users to grant third-party access to their web resources without sharing their passwords.
OAuth是个安全相关的协议,作用在于,使用户授权第三方的应用程序访问用户的web资源,并且不需要向第三方应用程序透露自己的密码。
OAuth 2.0是个全新的协议,并且不对之前的版本做向后兼容,然而,OAuth 2.0保留了与之前版本OAuth相同的整体架构。
因为我要跟一个客户的OAuth2.0服务器调试接口,客户那边反应比较慢,所以我打算自己搭一个OAuth2.0的服务器,所以就去网上找了一些资料,发现实现OAuth2.0服务有很多种方式:
1.第一种就是今天要讲的 使用Spring Security OAuth 框架搭建
2.第二种是cas 搭建OAuth2.0服务,这种暂时还没研究
3.应该还有其他的方式实现OAuth2.0服务
因为OAuth2.0只是一个协议,我的理解就是为了将客户端和服务端的认证和授权变得简单而且标准,所以产生了OAuth2.0协议,网络上有很多关于OAuth2.0认证和授权的步骤:
网上有很多种,可以自行百度。
我看了一篇关于搭建 Spring Security OAuth2.0 的文章 如下:https://www.cnblogs.com/softidea/p/6884395.html
也是按照文中的方式搭建的。
demo 可以 用如下地址下载(也是引入的上一篇博文中的):https://github.com/wanghongfei/spring-security-oauth2-example
在这里在此感谢一下这篇文章的作者:https://www.cnblogs.com/softidea/p/6884395.html
一。因为是Spring boot 项目,下载完之后使用idea打开。
二。因为是maven 项目 配置相应的Maven的地址,之后idea会自动 下载相应的jar包
三。第三步就是启动项目,这里我走了一些弯路,因为不熟悉Spring boot项目是如何启动的,我还像以前是的添加tomcat, 后来在添加的tomcat中添加对应的artifacted 发现没有(如下)
这里点击加号没有常规的artifactedId 然后我就直接选了项目文件夹,启动后发现,都访问不了,都是404,
后来还是一个同事的帮助下,启动了这个项目,在这里感谢一下这位同事。
启动如下截图:
点击右边的MavenProject 中项目的Plugins 中的 spring-boot 中的 spring-boot:run
这时项目就起来了。
四。在项目启动之前,还是得对下载的项目进行一些修改。
首先,1.先得新建一个 数据库,用于存放OAuth的一些信息:
这些在这篇文章中有写: https://www.cnblogs.com/softidea/p/6884395.html
下面我就直接摘抄,其中对数据库名字进行了修改:sql文件如下:
CREATE DATABASE oauth_db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER oauth@'%' IDENTIFIED BY '这里保密';
GRANT ALL ON oauth_db.* TO oauth;
CREATE SCHEMA IF NOT EXISTS `oauth_db` DEFAULT CHARACTER SET utf8 ;
USE `oauth_db` ;
CREATE TABLE IF NOT EXISTS `oauth_db`.`clientdetails` (
`appId` VARCHAR(128) NOT NULL,
`resourceIds` VARCHAR(256) NULL DEFAULT NULL,
`appSecret` VARCHAR(256) NULL DEFAULT NULL,
`scope` VARCHAR(256) NULL DEFAULT NULL,
`grantTypes` VARCHAR(256) NULL DEFAULT NULL,
`redirectUrl` VARCHAR(256) NULL DEFAULT NULL,
`authorities` VARCHAR(256) NULL DEFAULT NULL,
`access_token_validity` INT(11) NULL DEFAULT NULL,
`refresh_token_validity` INT(11) NULL DEFAULT NULL,
`additionalInformation` VARCHAR(4096) NULL DEFAULT NULL,
`autoApproveScopes` VARCHAR(256) NULL DEFAULT NULL,
PRIMARY KEY (`appId`))
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_access_token` (
`token_id` VARCHAR(256) NULL DEFAULT NULL,
`token` BLOB NULL DEFAULT NULL,
`authentication_id` VARCHAR(128) NOT NULL,
`user_name` VARCHAR(256) NULL DEFAULT NULL,
`client_id` VARCHAR(256) NULL DEFAULT NULL,
`authentication` BLOB NULL DEFAULT NULL,
`refresh_token` VARCHAR(256) NULL DEFAULT NULL,
PRIMARY KEY (`authentication_id`))
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_approvals` (
`userId` VARCHAR(256) NULL DEFAULT NULL,
`clientId` VARCHAR(256) NULL DEFAULT NULL,
`scope` VARCHAR(256) NULL DEFAULT NULL,
`status` VARCHAR(10) NULL DEFAULT NULL,
`expiresAt` DATETIME NULL DEFAULT NULL,
`lastModifiedAt` DATETIME NULL DEFAULT NULL)
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_client_details` (
`client_id` VARCHAR(128) NOT NULL,
`resource_ids` VARCHAR(256) NULL DEFAULT NULL,
`client_secret` VARCHAR(256) NULL DEFAULT NULL,
`scope` VARCHAR(256) NULL DEFAULT NULL,
`authorized_grant_types` VARCHAR(256) NULL DEFAULT NULL,
`web_server_redirect_uri` VARCHAR(256) NULL DEFAULT NULL,
`authorities` VARCHAR(256) NULL DEFAULT NULL,
`access_token_validity` INT(11) NULL DEFAULT NULL,
`refresh_token_validity` INT(11) NULL DEFAULT NULL,
`additional_information` VARCHAR(4096) NULL DEFAULT NULL,
`autoapprove` VARCHAR(256) NULL DEFAULT NULL,
PRIMARY KEY (`client_id`))
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_client_token` (
`token_id` VARCHAR(256) NULL DEFAULT NULL,
`token` BLOB NULL DEFAULT NULL,
`authentication_id` VARCHAR(128) NOT NULL,
`user_name` VARCHAR(256) NULL DEFAULT NULL,
`client_id` VARCHAR(256) NULL DEFAULT NULL,
PRIMARY KEY (`authentication_id`))
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_code` (
`code` VARCHAR(256) NULL DEFAULT NULL,
`authentication` BLOB NULL DEFAULT NULL)
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `oauth_db`.`oauth_refresh_token` (
`token_id` VARCHAR(256) NULL DEFAULT NULL,
`token` BLOB NULL DEFAULT NULL,
`authentication` BLOB NULL DEFAULT NULL)
ENGINE = INNODB
DEFAULT CHARACTER SET = utf8;
--插入数据
INSERT INTO oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
VALUES ('client', NULL, 'secret', 'app', 'authorization_code', 'http://www.baidu.com', NULL, NULL, NULL, NULL, NULL);
文中除了密码其他都是真实的。
最后一句插入的语句是 新建一个 应用并规定了 他的 redirect_url
接下来,就得修改application.properties 中关于对数据库的配置,然后启动项目。
我们按照博文https://www.cnblogs.com/softidea/p/6884395.html 中所写,访问如下地址:
localhost:8080/oauth/authorize?client_id=client&response_type=code&redirect_uri=http://www.baidu.com
之后就会出现如下登录界面,我们随便输入一个用户名和密码:
之后选择 Approve
点击:Authorize
就会跳转到百度页面:
并且接收到code
有了以上的这几步,
接下来就可以写一个OAuth2.0的客户端去访问我们刚刚的OAuth2.0的服务端获取code,然后再获取token,再通过token 去获取 用户信息。
那么我要在 oauth_client_details 表中再新建一条语句:
INSERT INTO oauth_client_details (client_id, resource_ids, client_secret, scope, authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove)
VALUES ('client02', NULL, 'secret', 'app', 'authorization_code', 'https://localhost:8443/cas/authcode', NULL, NULL, NULL, NULL, NULL);
其中 clientId 为 client02 secret为app redirect_url 为接收code的一个servlet 地址为:https://localhost:8443/cas/authcode
之后我们访问的地址就变了:
http://localhost:8080/oauth/authorize?client_id=client02&response_type=code&redirect_uri=https://localhost:8443/cas/authcode
接下来我们通过https://localhost:8443/cas/authcode 这个servlet 接收到code ,再通过 httpclient 使用code 去获取 access_token.
我是先使用postman 去使用code获取access_token的,然后再使用httpclient 获取access_token 时遇到一个问题,后来是因为没有设置content-type 设置为:
application/x-www-form-urlencoded
就对了。
以上只是一个简单的demo,写的很乱,只不过记录了一下当时遇到的问题和步骤,方便以后查看。
有问题欢迎指正,也可以在下面留言,也可以联系我QQ:1916791727
不积跬步,无以之千里
不积小流,无以成江海