基於spring-security-oauth2實現oauth2數據庫版(持續更新)

基於spring-security-oauth2實現oauth2數據庫版

文章代碼地址:連接描述能夠下載直接運行,基於springboot2.1.5,springcloud Greenwich版本實現mysql

該系列分爲兩個部分:分爲內存實現,數據庫實現。其中數據庫實現採用RBAC權限角色管理。git

上一篇,介紹了oauth2的內存實現,也就是認證服務把客戶端和用戶信息都存儲在內存中,這樣不利於拓展,不適合於生產環境。下面,咱們開始基於mysql數據庫的oauth2實現。
首先,咱們建立oauth2數據庫,注意編碼選擇utf-8mb4格式,utf-8是不規範的,mysql也沒有進行更改。 github

clipboard.png

好了,如今咱們初始化表,sql以下:web


Drop table if exists oauth_client_details;
create table oauth_client_details (
client_id VARCHAR(255) PRIMARY KEY,
resource_ids VARCHAR(255),
client_secret VARCHAR(255),
scope VARCHAR(255),
authorized_grant_types VARCHAR(255),
web_server_redirect_uri VARCHAR(255),
authorities VARCHAR(255),
access_token_validity INTEGER,
refresh_token_validity INTEGER,
additional_information TEXT,
autoapprove VARCHAR (255) default 'false'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;spring

Drop table if exists oauth_access_token;
create table oauth_access_token (
token_id VARCHAR(255),
token BLOB,
authentication_id VARCHAR(255),
user_name VARCHAR(255),
client_id VARCHAR(255),
authentication BLOB,
refresh_token VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;sql

Drop table if exists oauth_refresh_token;
create table oauth_refresh_token (
token_id VARCHAR(255),
token BLOB,
authentication BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;數據庫

Drop table if exists oauth_code;
create table oauth_code (
code VARCHAR(255),
authentication BLOB
) ENGINE=InnoDB DEFAULT CHARSET=utf8;segmentfault

-- Add indexes
create index token_id_index on oauth_access_token (token_id);
create index authentication_id_index on oauth_access_token (authentication_id);
create index user_name_index on oauth_access_token (user_name);
create index client_id_index on oauth_access_token (client_id);
create index refresh_token_index on oauth_access_token (refresh_token);
create index token_id_index on oauth_refresh_token (token_id);
create index code_index on oauth_code (code);springboot

-- INSERT DEFAULT DATA
INSERT INTO oauth_client_details VALUES ('dev', '', 'dev', 'app', 'authorization_code', 'http://localhost:7777/', '', '3600', '3600', '{"country":"CN","country_code":"086"}', 'TAIJI');mybatis

-- ----------------------------
-- Table structure for tb_user
-- ----------------------------
DROP TABLE IF EXISTS tb_user;
CREATE TABLE tb_user (

`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
                       `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '用戶名',
                       `password` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密碼',
                       `gender` int(2) DEFAULT NULL COMMENT '性別(1男 2女)',
                       `email` varchar(128) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '郵箱',
                       `create_time` datetime DEFAULT NULL COMMENT '用戶建立時間',
                       `update_time` datetime DEFAULT NULL COMMENT '更新時間',
                       `removed` int(2) DEFAULT NULL COMMENT '是否刪除(1刪除0未刪除)',
                       PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of tb_user
-- ----------------------------
BEGIN;
INSERT INTO tb_user VALUES (1, 'admin', '$2a$10$vWyL7fMGQRvVNn.i2bK40e3z30Nem4k.ElwuxdLBNzKFxRCcXCoqm', 1, NULL, '2019-05-30 15:53:45', '2019-05-30 15:53:51', 0);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

-- ----------------------------
-- Table structure for tb_user_role
-- ----------------------------
DROP TABLE IF EXISTS tb_user_role;
CREATE TABLE tb_user_role (

`id` bigint(11) NOT NULL COMMENT '主鍵ID',
                            `user_id` bigint(11) DEFAULT NULL COMMENT '用戶主鍵',
                            `role_id` bigint(11) DEFAULT NULL COMMENT '角色ID',
                            PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of tb_user_role
-- ----------------------------
BEGIN;
INSERT INTO tb_user_role VALUES (1, 1, 1);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

-- ----------------------------
-- Table structure for tb_role
-- ----------------------------
DROP TABLE IF EXISTS tb_role;
CREATE TABLE tb_role (

`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
                       `parent_id` bigint(20) DEFAULT NULL COMMENT '父類ID',
                       `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色名字',
                       `ename` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色名字',
                       `description` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '描述',
                       `create_time` datetime DEFAULT NULL COMMENT '建立時間',
                       `update_time` datetime DEFAULT NULL COMMENT '更新時間',
                       PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of tb_role
-- ----------------------------
BEGIN;
INSERT INTO tb_role VALUES (1, 0, '超級管理員', 'ADMIN', NULL, '2019-05-30 16:09:53', '2019-05-30 16:09:57');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

-- ----------------------------
-- Table structure for tb_role_permission
-- ----------------------------
DROP TABLE IF EXISTS tb_role_permission;
CREATE TABLE tb_role_permission (

`id` bigint(11) NOT NULL COMMENT '主鍵ID',
                                  `role_id` bigint(11) DEFAULT NULL COMMENT '角色ID',
                                  `permission_id` bigint(11) DEFAULT NULL COMMENT '權限ID',
                                  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of tb_role_permission
-- ----------------------------
BEGIN;
INSERT INTO tb_role_permission VALUES (1, 1, 1);
INSERT INTO tb_role_permission VALUES (2, 1, 2);
INSERT INTO tb_role_permission VALUES (3, 1, 3);
INSERT INTO tb_role_permission VALUES (4, 1, 4);
INSERT INTO tb_role_permission VALUES (5, 1, 5);
INSERT INTO tb_role_permission VALUES (6, 1, 6);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

-- ----------------------------
-- Table structure for tb_permission
-- ----------------------------
DROP TABLE IF EXISTS tb_permission;
CREATE TABLE tb_permission (

`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
                             `parent_id` bigint(11) DEFAULT NULL COMMENT '用戶ID',
                             `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '權限名字',
                             `ename` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '權限名字',
                             `url` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '請求路徑',
                             `description` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '描述',
                             `create_time` datetime DEFAULT NULL COMMENT '建立時間',
                             `update_time` datetime DEFAULT NULL COMMENT '更新時間',
                             PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

-- ----------------------------
-- Records of tb_permission
-- ----------------------------
BEGIN;
INSERT INTO tb_permission VALUES (1, 0, '系統管理', 'System', '/', NULL, '2019-05-30 16:22:20', '2019-05-30 16:22:24');
INSERT INTO tb_permission VALUES (2, 0, '用戶管理', 'SystemUser', '/users', NULL, '2019-05-30 16:23:28', '2019-05-30 16:23:32');
INSERT INTO tb_permission VALUES (3, 0, '查看用戶', 'SystemUserView', NULL, NULL, '2019-05-30 16:24:29', '2019-05-30 16:24:33');
INSERT INTO tb_permission VALUES (4, 0, '新增用戶', 'SystemUserInsert', NULL, NULL, '2019-05-30 16:25:09', '2019-05-30 16:25:13');
INSERT INTO tb_permission VALUES (5, 0, '編輯用戶', 'SystemUserUpdate', NULL, NULL, '2019-05-30 16:25:53', '2019-05-30 16:25:57');
INSERT INTO tb_permission VALUES (6, 0, '刪除用戶', 'SystemUserDelete', NULL, NULL, '2019-05-30 16:26:49', '2019-05-30 16:26:54');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;


咱們看看錶結構:

clipboard.png
簡單介紹,這是把客戶端配置從內存中轉移到oauth_client_details表中,字段意思請參考上一篇連接描述

oauth_access_token: access_token 表結構:

clipboard.png
oauth_code表結構:

clipboard.png
oauth_refresh_token表結構:

clipboard.png
下面是用戶信息表:
tb_user表:

clipboard.png
tb_user_role表結構:

clipboard.png
tb_role表結構:

clipboard.png
tb_role_permission表結構:

clipboard.png
tb_permission表結構:

clipboard.png

好了,表設計完成。下面咱們開始編碼:

(1)咱們把以前的項目複製一份修更名字,添加依賴:

clipboard.png
咱們添加數據庫的依賴,使用mybatis做爲持久層框架。

(2)下面是項目結構:

clipboard.png

這裏介紹intellij的mybatis自動生成插件easycode,只要配置好數據庫鏈接,能夠自動生成domain,mapper,xml等文件。
首先,修改WebSecurityConfig文件以下:

clipboard.png
這裏將內存換到數據庫,使用userDetailsService,由於,咱們須要注入UserDetailsService,建立UserDetailsServiceImpl文件

clipboard.png
這裏實現UserDetailsService接口,實現loadUserByUsername方法,這個方法根據用戶名查詢用戶信息,查詢用戶權限,返回認證用戶import org.springframework.security.core.userdetails.User; userdetails包下的User對象。
這裏重點介紹一下查詢權限的sql:

clipboard.png
經過連表用戶,角色,權限等連表查詢權限。

(3)用戶驗證完成,開始認證處理,修改AuthConfig以下:

clipboard.png
這裏咱們將客戶端client放到數據庫,使用JdbcClientDetailsService。建立service的時候,須要使用DataSource數據源,從數據庫查詢。使用jdbcTokenStore存儲token。
(4)建立OauthPasswordConfig配置注入BCrytpPasswordEncoder對象:

clipboard.png
(5)實體類以下:

clipboard.png

clipboard.png
(6)應用配置文件:

clipboard.png
(7)完成,如今咱們使用9001端口啓動應用:

clipboard.png
(8)啓動成功,咱們訪問地址:
http://localhost:9001/oauth/oauthorize?client_id=client&response_type=code/
以下:

clipboard.png
輸入帳戶:admin 密碼: 123456 點擊登陸:

clipboard.png
贊成受權

clipboard.png
跳轉成功,咱們使用code,訪問這個地址,獲取token
http://client:secret@http://localhost:9001/oauth/token

clipboard.png
獲得結果:

clipboard.png成功,獲得access_token。 基於數據庫的認證服務完成。未完待續,下一篇介紹單點登陸 有問題,請留言。

相關文章
相關標籤/搜索