<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 基礎Web工程的建設 ### 創建父項目 > 命名:cloudframe ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.gosuncn</groupId> <artifactId>cloudframe</artifactId> <version>1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR1</spring-cloud.version> <spring.cloud.alibaba.version>2.2.0.RELEASE</spring.cloud.alibaba.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring.cloud.alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project> ``` ### 創建公共子模塊 > 命名:common ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloudframe</artifactId> <groupId>com.gosuncn</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>common</artifactId> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> </project> ``` 此時父項目自動更改 ```xml ... <groupId>com.gosuncn</groupId> <artifactId>cloudframe</artifactId> <packaging>pom</packaging> <version>1.0</version> <modules> <module>common</module> </modules> ... ``` ##### 創建Main方法函數 ```java package com.gosuncn; public class MainStarter { public static void main(String[] args) { } } ``` ##### 創建封裝響應類 ```java package com.gosuncn.bean; @Data @NoArgsConstructor @AllArgsConstructor public class CommonResult<T> implements Serializable { /** * 狀態碼 */ private Integer code; /** * 狀態說明 */ private String msg; /** * 數據內容 */ private T data; } ``` 其他模塊引入公用模塊可以共用此類來封裝響應。 ### 創建認證授權模塊 > 命名:authorize ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloudframe</artifactId> <groupId>com.gosuncn</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>authorize</artifactId> <dependencies> <dependency> <groupId>com.gosuncn</groupId> <artifactId>common</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project> ``` ##### 創建測試控制器 ```java package com.gosuncn.controller; @RestController public class UserController { @GetMapping("/users") public CommonResult getUsers() { return new CommonResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), "Hello, I'm Apollo."); } } ``` ##### 創建配置文件 > application.yml ```yaml server: port: 80 ``` ##### 測試 ```http http://127.0.0.1/users ``` ```json {"code":200,"msg":"OK","data":"Hello, I'm Apollo."} ``` # 創建數據庫表結構 ### 創建表結構 創建`sys_rbac`數據庫。在庫中,創建RBAC經典表結構:用戶表、角色表、權限表以及兩張中間表,最后創建一張表`oauth_client_details`,它用來存儲第三方客戶端信息,主要用于OAuth2協議。 ```mysql CREATE DATABASE `sys_rbac` CHARACTER SET 'utf8' COLLATE 'utf8_bin'; USE `sys_rbac`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶ID', `username` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用戶名', `password` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '密碼', `enabled` tinyint(1) NULL DEFAULT 1 COMMENT '啟用狀態[1:啟用][0:未啟用]', PRIMARY KEY (`id`) USING BTREE, UNIQUE INDEX `index_user_username`(`username`) USING BTREE COMMENT '用戶名唯一索引' ); CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色ID', `name` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '角色名稱', `desc` char(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '角色描述', PRIMARY KEY (`id`) USING BTREE ); CREATE TABLE `access` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '權限ID', `name` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '權限名稱', `desc` char(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '權限描述', PRIMARY KEY (`id`) USING BTREE ); CREATE TABLE `user_role` ( `user_id` int(11) NOT NULL COMMENT '用戶ID', `role_id` int(11) NOT NULL COMMENT '角色ID', INDEX `fk_user_role_role_id`(`role_id`) USING BTREE, INDEX `fk_user_role_user_id`(`user_id`) USING BTREE, CONSTRAINT `fk_user_role_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_user_role_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE `role_access` ( `role_id` int(11) NOT NULL COMMENT '角色ID', `access_id` int(11) NOT NULL COMMENT '權限ID', INDEX `fk_role_access_role_id`(`role_id`) USING BTREE, INDEX `fk_role_access_access_id`(`access_id`) USING BTREE, CONSTRAINT `fk_role_access_access_id` FOREIGN KEY (`access_id`) REFERENCES `access` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_role_access_role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ); CREATE TABLE `oauth_client_details` ( `client_id` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, `resource_ids` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `client_secret` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `scope` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `authorized_grant_types` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `web_server_redirect_uri` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `authorities` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `access_token_validity` int(11) NULL DEFAULT NULL, `refresh_token_validity` int(11) NULL DEFAULT NULL, `additional_information` varchar(4096) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, `autoapprove` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL, PRIMARY KEY (`client_id`) USING BTREE ); ``` `authorized_grant_types`授權類型可選值有:`authorization_code`,`implicit`,`password`,`client_credentials`,`refresh_token` 多個值用`,`分割。 ### 插入模擬數據 ```mysql INSERT INTO `sys_rbac`.`user` ( `id`, `username`, `password`, `enabled` ) VALUES ( 1, 'user', '$2a$10$1hZj6YmqJ81Dkpuitsl3S.CHVzJXJN2b5srKMgGexLzFQU5jlZbgu', 1 ); INSERT INTO `sys_rbac`.`role`(`id`, `name`, `desc`) VALUES (1, 'ADMIN', '管理員'); INSERT INTO `sys_rbac`.`access`(`id`, `name`, `desc`) VALUES (1, 'all', '測試數據'); INSERT INTO `sys_rbac`.`user_role`(`user_id`, `role_id`) VALUES (1, 1); INSERT INTO `sys_rbac`.`role_access`(`role_id`, `access_id`) VALUES (1, 1); INSERT INTO `sys_rbac`.`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 ('web', NULL, '$2a$10$fvyMIE99J59EBj1K/huJ0ethuO7LnAfKFwjuUl5Pz36zLUw61UWie', 'all', 'authorization_code,implicit,password,client_credentials,refresh_token' , 'http://www.baidu.com', NULL, NULL, NULL, NULL , 'true'); ``` # 引入MyBatis框架 ### 添加MyBatis相關依賴 ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloudframe</artifactId> <groupId>com.gosuncn</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>authorize</artifactId> <dependencies> <dependency> <groupId>com.gosuncn</groupId> <artifactId>common</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>com/gosuncn/dao/*.xml</include> </includes> </resource> </resources> </build> </project> ``` 其中,`<build>`···`</build>`這段是為了maven可將mapper的xml文件可與dao接口寫在一起。 ### 添加數據源和mybatis配置信息 ```yaml server: port: 80 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql:///sys_rbac?serverTimezone=UTC username: root password: root mybatis: mapper-locations: classpath*:/com/gosuncn/dao/*.xml ``` ### 創建實體類 ##### 創建user表對應實體類User類 ```java package com.gosuncn.entity; @Data public class User { private Integer id; private String username; private String password; private Boolean enabled; } ``` ##### 創建role表對應實體類Role類 ```java package com.gosuncn.entity; @Data public class Role { private Integer id; private String name; private String desc; } ``` ##### 創建access表對應實體類Access類 ```java package com.gosuncn.entity; @Data public class Access { private Integer id; private String name; private String desc; } ``` ### 創建UserMapper接口 ```java package com.gosuncn.dao; @Mapper public interface UserMapper { User getUserByUsername(@Param("username") String username); } ``` ### 創建UserMapper.xml文件 ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.gosuncn.dao.UserMapper"> <select id="getUserByUsername" parameterType="java.lang.String" resultType="com.gosuncn.entity.User"> SELECT `id`, `username`, `password`, `enabled` FROM `user` WHERE `username` = #{username} </select> </mapper> ``` ### 創建UserService類 ```java package com.gosuncn.service; @Service public class UserService { @Autowired private UserMapper userMapper; Optional<User> getUserByUsername(String username) { return Optional.ofNullable(userMapper.getUserByUsername(username)); } } ``` ### 修改UserController類 ```java package com.gosuncn.controller; @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/user") public CommonResult getUserByUsername(@RequestParam String username) { return new CommonResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), userService.getUserByUsername(username).orElse(null)); } } ``` ### 啟動項目測試 ##### 訪問存在的用戶 ```http http://127.0.0.1/user?username=user ``` ```json { "code": 200, "msg": "OK", "data": { "id": 1, "username": "user", "password": "$2a$10$1hZj6YmqJ81Dkpuitsl3S.CHVzJXJN2b5srKMgGexLzFQU5jlZbgu", "enabled": true } } ``` ##### 訪問不存在的用戶 ```http http://127.0.0.1/user?username=Apollo ``` ```json {"code":200,"msg":"OK","data":null} ``` # 生成PrivateKey ### 生成私鑰命令 因為在oauth2協議中,我們用到了非對稱加密算法,因此,我們先生成放在認證服務器端的私鑰: ```shell keytool -genkeypair -alias cigcjks -keyalg RSA -keypass cigcjks -keystore cigc.jks -storepass cigcjks ``` 通過上面命令,我們得到了一個`cigc.jks`文件。 ### 具體說明 ```shell keytool -genkeypair -alias keyname -keyalg RSA -keypass keyword -keystore file.jks -storepass fileword ``` - keyname 生成的密鑰對的名稱 - keyword 生成的密鑰對的密碼 - file.jks 生成的密鑰對的文件名 - fileword 生成的密鑰對的文件名的密碼 > 其中,`keyname、keyword、file.jks、fileword`均是可以自己定義修改的,建議遵守常規命名規范。示例: > > keytool -genkeypair -alias key0001 -keyalg RSA -keypass wVsE6k -keystore cigc.jks -storepass TX0zAg --- ### 安置私鑰 在項目的`resources`目錄下,新建一個名為`PrivateKey`的目錄。將`cigc.jks`文件放入`PrivateKey`目錄中,以備后用。 # 生成PublicKey ### 生成公鑰命令 公鑰是放在資源服務器上的文件,目前先做出來準備后用。 ```shell keytool -list -rfc --keystore file.jks | openssl x509 -inform pem -pubkey ``` - file.jks 生成的密鑰對的文件名 > 示例: > > keytool -list -rfc --keystore cigc.jks | openssl x509 -inform pem -pubkey --- ### 演示例子 接下來,我們就執行命令,記住了,一定在與`jks`文件同級目錄下,否則找不到`jks`文件。 ```shell keytool -list -rfc --keystore cigc.jks | openssl x509 -inform pem -pubkey ``` 輸入密碼:cigcjks(生成PrivateKey這一步時,設置的密碼。)得到: ``` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMQg2pRayMgZD3E8z4iD ev7FpOk5ljyiF3jUNPLcPtX2fnEYQsQTc8af85Mk+Q8jH5icqlkJOs+0KsBH899m AjWNU6yppySq5jklp5vg3TMK+ShO4VRC+/b2aJwqbGYoPHDrgMu7xpl3eaFJiwcj oeNIsPQYTL5UlzROGFjO0CkXaRRq/sRHhJbRL2kBey8i/+gB8GACpgq/GeRREJu0 XzLO5sgSeRG5OyzNeURvCS2D9mtx4o86WDicIjev3hVjubKyhNumILk/ZV4zPQy/ k2T+DnyoapAFg/6xK2NxQdkFEu7/kma9tde6Uj1QDVvzXf89ZWnPSPEzaHVACzZk pwIDAQAB -----END PUBLIC KEY----- -----BEGIN CERTIFICATE----- MIIDUzCCAjugAwIBAgIEEUTVCjANBgkqhkiG9w0BAQsFADBaMQ0wCwYDVQQGEwRj aWdjMQ0wCwYDVQQIEwRjaWdjMQ0wCwYDVQQHEwRjaWdjMQ0wCwYDVQQKEwRjaWdj MQ0wCwYDVQQLEwRjaWdjMQ0wCwYDVQQDEwRjaWdjMB4XDTIwMDQyODA2NTM1MFoX DTIwMDcyNzA2NTM1MFowWjENMAsGA1UEBhMEY2lnYzENMAsGA1UECBMEY2lnYzEN MAsGA1UEBxMEY2lnYzENMAsGA1UEChMEY2lnYzENMAsGA1UECxMEY2lnYzENMAsG A1UEAxMEY2lnYzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALjEINqU WsjIGQ9xPM+Ig3r+xaTpOZY8ohd41DTy3D7V9n5xGELEE3PGn/OTJPkPIx+YnKpZ CTrPtCrAR/PfZgI1jVOsqackquY5Jaeb4N0zCvkoTuFUQvv29micKmxmKDxw64DL u8aZd3mhSYsHI6HjSLD0GEy+VJc0ThhYztApF2kUav7ER4SW0S9pAXsvIv/oAfBg AqYKvxnkURCbtF8yzubIEnkRuTsszXlEbwktg/ZrceKPOlg4nCI3r94VY7mysoTb piC5P2VeMz0Mv5Nk/g58qGqQBYP+sStjcUHZBRLu/5JmvbXXulI9UA1b813/PWVp z0jxM2h1QAs2ZKcCAwEAAaMhMB8wHQYDVR0OBBYEFDJG8MKxT5rgKgtfRIK9iPSx ZejzMA0GCSqGSIb3DQEBCwUAA4IBAQAE/5ouShSwaOIrq13FZt9VDzAZdyXjZ5Ly wImfH+bsdtIRB3wbRml3fNClw9gfivwbAuvVZb11nJM3bdrzUcKVnzd7dvXRj9w4 /aaXcyVjBwE6uBCyMn2k8enOdf1BNkAurS/yhmPo4lCrJS70LNAw+y7dw+dQVuKa wUiJ8330cIRKMhll/kFIVE6np55tPG2jAEY63WnN/bDDHRZIUQplqfe6YGOmG5wu 5ViZdAmRRtaC/g51SzrIvmiJV5CdI5s4FOt8r2QCXKLBbLtYlhSZONc471HWpRz5 P2vb4cg8UjlaUEH0j4u3biCaqtWelHOiT5qJeOkhHveZOwiiwASG -----END CERTIFICATE----- ``` --- 我們將以下內容部分拷貝下來: ``` -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMQg2pRayMgZD3E8z4iD ev7FpOk5ljyiF3jUNPLcPtX2fnEYQsQTc8af85Mk+Q8jH5icqlkJOs+0KsBH899m AjWNU6yppySq5jklp5vg3TMK+ShO4VRC+/b2aJwqbGYoPHDrgMu7xpl3eaFJiwcj oeNIsPQYTL5UlzROGFjO0CkXaRRq/sRHhJbRL2kBey8i/+gB8GACpgq/GeRREJu0 XzLO5sgSeRG5OyzNeURvCS2D9mtx4o86WDicIjev3hVjubKyhNumILk/ZV4zPQy/ k2T+DnyoapAFg/6xK2NxQdkFEu7/kma9tde6Uj1QDVvzXf89ZWnPSPEzaHVACzZk pwIDAQAB -----END PUBLIC KEY----- ``` ### 保存公鑰 新建一個文件,名為:`public.cert`。將內容拷貝進文件中。以備后用。 # 完善角色和權限數據交互 ### 創建RoleMapper接口 ```java package com.gosuncn.dao; @Mapper public interface RoleMapper { List<Role> getRolesByUserId(@Param("userId") Integer userId); } ``` ### 創建RoleMapper.xml文件 ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.gosuncn.dao.RoleMapper"> <select id="getRolesByUserId" parameterType="java.lang.Integer" resultType="com.gosuncn.entity.Role"> SELECT `role`.`id`, `role`.`name`, `role`.`desc` FROM `user_role` LEFT JOIN `role` ON `user_role`.`role_id` = `role`.`id` WHERE `user_role`.`user_id` = #{userId} </select> </mapper> ``` ### 創建AccessMapper接口 ```java package com.gosuncn.dao; @Mapper public interface AccessMapper { List<Access> getAccessesByRoleId(@Param("roleId") Integer roleId); } ``` ### 創建AccessMapper.xml文件 ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.gosuncn.dao.AccessMapper"> <select id="getAccessesByRoleId" parameterType="java.lang.Integer" resultType="com.gosuncn.entity.Access"> SELECT `id`, `name`, `desc` FROM `role_access` LEFT JOIN `access` ON `role_access`.`access_id` = `access`.`id` WHERE `role_access`.`role_id` = #{roleId} </select> </mapper> ``` ### 創建RoleService類 ```java package com.gosuncn.service; @Service public class RoleService { @Autowired private RoleMapper roleMapper; public Optional<List<Role>> getRolesByUserId(Integer userId) { return Optional.ofNullable(roleMapper.getRolesByUserId(userId)); } } ``` ### 創建AccessService類 ```java package com.gosuncn.service; @Service public class AccessService { @Autowired private AccessMapper accessMapper; public Optional<List<Access>> getAccessesByRoleId(Integer roleId) { return Optional.ofNullable(accessMapper.getAccessesByRoleId(roleId)); } } ``` ### 修改UserController類 ```java package com.gosuncn.controller; @RestController public class UserController { @Autowired private UserService userService; @Autowired private RoleService roleService; @Autowired private AccessService accessService; @GetMapping("/user") public CommonResult getUserByUsername(@RequestParam String username) { return new CommonResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), userService.getUserByUsername(username).orElse(null)); } @GetMapping("/role/userId/{userId}") public CommonResult getRolesByUserId(@PathVariable("userId") Integer userId) { return new CommonResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), roleService.getRolesByUserId(userId).orElse(null)); } @GetMapping("/access/roleId/{roleId}") public CommonResult getAccessesByRoleId(@PathVariable("roleId") Integer roleId) { return new CommonResult(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), accessService.getAccessesByRoleId(roleId).orElse(null)); } } ``` ### 啟動項目測試 ```http http://127.0.0.1/role/userId/1 ``` ```json {"code":200,"msg":"OK","data":[{"id":1,"name":"ADMIN","desc":"管理員"}]} ``` ```http http://127.0.0.1/access/roleId/1 ``` ```json {"code":200,"msg":"OK","data":[{"id":1,"name":"all","desc":"測試數據"}]} ``` # OAuth2協議防護系統 ### 引入依賴 ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> ``` ##### pom文件完整版 ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>cloudframe</artifactId> <groupId>com.gosuncn</groupId> <version>1.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>authorize</artifactId> <dependencies> <dependency> <groupId>com.gosuncn</groupId> <artifactId>common</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>com/gosuncn/dao/*.xml</include> </includes> </resource> </resources> </build> </project> ``` ### 自定義UserDetails > 類名:AuthUserDetails ```java package com.gosuncn.entity; public class AuthUserDetails implements UserDetails { private Integer id; // 用戶id private String username; // 用戶名 private String password; // 密碼 private Boolean enabled; // 是否啟用 private List<GrantedAuthority> authorities; // 權限列表 public AuthUserDetails(User user, List<GrantedAuthority> authorities) { this(user.getId(), user.getUsername(), user.getPassword(), user.getEnabled(), authorities); } public AuthUserDetails(Integer id, String username, String password, Boolean enabled, List<GrantedAuthority> authorities) { this.id = id; this.username = username; this.password = password; this.enabled = enabled; this.authorities = authorities; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.authorities; } @Override public String getPassword() { return this.password; } @Override public String getUsername() { return this.username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return this.enabled; } } ``` ### 自定義UserDetailsService > 類名:AuthUserDetailsService ```java package com.gosuncn.service; @Service @AllArgsConstructor public class AuthUserDetailsService implements UserDetailsService { private final static String ROLE_PREFIX = "ROLE_"; private final static String SEPARATED_STRING = ","; @Autowired private UserMapper userMapper; @Autowired private RoleMapper roleMapper; @Autowired private AccessMapper accessMapper; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userMapper.getUserByUsername(username); if (user == null) { return new AuthUserDetails(-1, username, "unknown", false, Collections.EMPTY_LIST); } StringBuilder authorityBuilder = new StringBuilder(); for (Role role : roleMapper.getRolesByUserId(user.getId())) { authorityBuilder.append(ROLE_PREFIX + role.getName()); for (Access access : accessMapper.getAccessesByRoleId(role.getId())) { authorityBuilder.append(SEPARATED_STRING).append(access.getName()); } } return new AuthUserDetails(user, AuthorityUtils.commaSeparatedStringToAuthorityList(authorityBuilder.toString())); } } ``` ### 配置認證成功處理 ```java package com.gosuncn.config; @Component public class AuthSuccessHandler implements AuthenticationSuccessHandler { private static final String CONTENT_TYPE = "application/json; charset=UTF-8"; @Autowired private ObjectMapper objectMapper; @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { response.setContentType(CONTENT_TYPE); response.getWriter().write(objectMapper.writeValueAsString(new CommonResult<>(HttpStatus.OK.value(), HttpStatus.OK.getReasonPhrase(), authentication))); } } ``` > 將authentication暴露只是測試實驗,實際投入生產切不可暴露。 ### 配置認證失敗處理 ```java package com.gosuncn.config; @Component public class AuthFailureHandler implements AuthenticationFailureHandler { private static final String CONTENT_TYPE = "application/json; charset=UTF-8"; @Autowired private ObjectMapper objectMapper; @Override public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { response.setContentType(CONTENT_TYPE); response.getWriter().write(objectMapper.writeValueAsString(new CommonResult<>(HttpStatus.FORBIDDEN.value(), HttpStatus.FORBIDDEN.getReasonPhrase(), exception.getMessage()))); } } ``` ### 創建SpringSecurity配置文件 ```java @Configuration @AllArgsConstructor public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final PasswordEncoder passwordEncoder; private final UserDetailsService userDetailsService; private final AuthSuccessHandler successHandler; private final AuthFailureHandler failureHandler; @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder); } @Override protected void configure(HttpSecurity http) throws Exception { http.formLogin() .permitAll() .successHandler(successHandler) .failureHandler(failureHandler); http.authorizeRequests() .anyRequest().authenticated(); http.csrf() .disable(); } } ``` ### 配置PasswordEncoder密碼編碼器 ```java package com.gosuncn.config; @Configuration public class PasswordEncoderConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` ### 配置token存儲策略 ##### 創建配置TokenStoreConfig類 ```java package com.gosuncn.config; import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory; @Configuration public class TokenStoreConfig { private static final String DIR_NAME = "PrivateKey" + "/"; @Value("${cloudframe.private-key}") private String privateKey; @Value("${cloudframe.key-password}") private String keyPassword; @Value("${cloudframe.alias}") private String alias; @Bean public TokenStore tokenStore() { return new JwtTokenStore(accessTokenConverter()); } @Bean public JwtAccessTokenConverter accessTokenConverter() { JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); converter.setKeyPair(new KeyStoreKeyFactory(new ClassPathResource(DIR_NAME + privateKey), keyPassword.toCharArray()).getKeyPair(alias)); return converter; } } ``` ##### 修改配置文件application.yml ```yaml server: port: 80 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql:///sys_rbac?serverTimezone=UTC username: root password: root mybatis: mapper-locations: classpath*:/com/gosuncn/dao/*.xml cloudframe: private-key: cigc.jks key-password: cigcjks alias: cigcjks ``` ### 創建授權服務器配置文件 ```java package com.gosuncn.config; import javax.sql.DataSource; @Configuration @AllArgsConstructor @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { private final TokenStore tokenStore; private final AuthenticationManager authenticationManager; private final JwtAccessTokenConverter accessTokenConverter; private final DataSource dataSource; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.withClientDetails(new JdbcClientDetailsService(dataSource)); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { endpoints .tokenStore(tokenStore) .accessTokenConverter(accessTokenConverter) .authenticationManager(authenticationManager) .allowedTokenEndpointRequestMethods(HttpMethod.POST); } @Override public void configure(AuthorizationServerSecurityConfigurer security) { security .tokenKeyAccess("permitAll()") .allowFormAuthenticationForClients(); } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看