From 1746a24afe754357ca325f5fb921b8a7174392e3 Mon Sep 17 00:00:00 2001 From: AlexBob Date: Thu, 7 Mar 2024 11:38:57 +0800 Subject: [PATCH] add moudle authorization server. --- boot/authorization/build.gradle | 7 +- .../config/AuthorizationServerConfig.java | 10 + .../authorization/config/SecurityConfig.java | 36 +++ .../authorization/core/Authorization.java | 76 ++++++ .../core/AuthorizationConsent.java | 24 ++ .../com/plate/authorization/core/Client.java | 52 ++++ .../src/main/resources/application-local.yml | 22 ++ .../src/main/resources/application.yml | 48 +++- .../src/main/resources/data-postgres.sql | 40 --- .../src/main/resources/schema-postgres.sql | 231 +++++------------- .../src/main/resources/static/index.html | 10 + 11 files changed, 340 insertions(+), 216 deletions(-) create mode 100644 boot/authorization/src/main/java/com/plate/authorization/config/AuthorizationServerConfig.java create mode 100644 boot/authorization/src/main/java/com/plate/authorization/config/SecurityConfig.java create mode 100644 boot/authorization/src/main/java/com/plate/authorization/core/Authorization.java create mode 100644 boot/authorization/src/main/java/com/plate/authorization/core/AuthorizationConsent.java create mode 100644 boot/authorization/src/main/java/com/plate/authorization/core/Client.java create mode 100644 boot/authorization/src/main/resources/application-local.yml delete mode 100644 boot/authorization/src/main/resources/data-postgres.sql create mode 100644 boot/authorization/src/main/resources/static/index.html diff --git a/boot/authorization/build.gradle b/boot/authorization/build.gradle index e4a5e5c0..ec99fad1 100644 --- a/boot/authorization/build.gradle +++ b/boot/authorization/build.gradle @@ -54,9 +54,12 @@ tasks.named("bootBuildImage") { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-redis' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-authorization-server' - implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.postgresql:postgresql' + + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-authorization-server' + implementation("org.springframework.boot:spring-boot-starter-security") + compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' diff --git a/boot/authorization/src/main/java/com/plate/authorization/config/AuthorizationServerConfig.java b/boot/authorization/src/main/java/com/plate/authorization/config/AuthorizationServerConfig.java new file mode 100644 index 00000000..1104968d --- /dev/null +++ b/boot/authorization/src/main/java/com/plate/authorization/config/AuthorizationServerConfig.java @@ -0,0 +1,10 @@ +package com.plate.authorization.config; + +import org.springframework.context.annotation.Configuration; + +/** + * @author Alex bob(Alex Bob) + */ +@Configuration +public class AuthorizationServerConfig { +} \ No newline at end of file diff --git a/boot/authorization/src/main/java/com/plate/authorization/config/SecurityConfig.java b/boot/authorization/src/main/java/com/plate/authorization/config/SecurityConfig.java new file mode 100644 index 00000000..fe2d0db8 --- /dev/null +++ b/boot/authorization/src/main/java/com/plate/authorization/config/SecurityConfig.java @@ -0,0 +1,36 @@ +package com.plate.authorization.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.security.config.Customizer; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; +import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; + +/** + * @author Alex bob(Alex Bob) + */ +@Configuration +public class SecurityConfig { + + @Bean + public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) + throws Exception { + OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) + .oidc(Customizer.withDefaults()); + http.exceptionHandling((exceptions) -> exceptions + .defaultAuthenticationEntryPointFor( + new LoginUrlAuthenticationEntryPoint("/login"), + new MediaTypeRequestMatcher(MediaType.TEXT_HTML) + ) + ).oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())); + + return http.cors(Customizer.withDefaults()).build(); + } + +} \ No newline at end of file diff --git a/boot/authorization/src/main/java/com/plate/authorization/core/Authorization.java b/boot/authorization/src/main/java/com/plate/authorization/core/Authorization.java new file mode 100644 index 00000000..52a44ede --- /dev/null +++ b/boot/authorization/src/main/java/com/plate/authorization/core/Authorization.java @@ -0,0 +1,76 @@ +package com.plate.authorization.core; + +import jakarta.persistence.*; +import lombok.Data; + +import java.io.Serializable; +import java.time.Instant; + +/** + * @author Alex bob(Alex Bob) + */ +@Data +@Entity +@Table(name = "oauth2_authorization") +public class Authorization implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + private String registeredClientId; + private String principalName; + private String authorizationGrantType; + @Column(length = 1000) + private String authorizedScopes; + @Column(length = 4000) + private String attributes; + @Column(length = 500) + private String state; + + @Column(length = 4000) + private String authorizationCodeValue; + private Instant authorizationCodeIssuedAt; + private Instant authorizationCodeExpiresAt; + private String authorizationCodeMetadata; + + @Column(length = 4000) + private String accessTokenValue; + private Instant accessTokenIssuedAt; + private Instant accessTokenExpiresAt; + @Column(length = 2000) + private String accessTokenMetadata; + private String accessTokenType; + @Column(length = 1000) + private String accessTokenScopes; + + @Column(length = 4000) + private String refreshTokenValue; + private Instant refreshTokenIssuedAt; + private Instant refreshTokenExpiresAt; + @Column(length = 2000) + private String refreshTokenMetadata; + + @Column(length = 4000) + private String oidcIdTokenValue; + private Instant oidcIdTokenIssuedAt; + private Instant oidcIdTokenExpiresAt; + @Column(length = 2000) + private String oidcIdTokenMetadata; + @Column(length = 2000) + private String oidcIdTokenClaims; + + @Column(length = 4000) + private String userCodeValue; + private Instant userCodeIssuedAt; + private Instant userCodeExpiresAt; + @Column(length = 2000) + private String userCodeMetadata; + + @Column(length = 4000) + private String deviceCodeValue; + private Instant deviceCodeIssuedAt; + private Instant deviceCodeExpiresAt; + @Column(length = 2000) + private String deviceCodeMetadata; + +} \ No newline at end of file diff --git a/boot/authorization/src/main/java/com/plate/authorization/core/AuthorizationConsent.java b/boot/authorization/src/main/java/com/plate/authorization/core/AuthorizationConsent.java new file mode 100644 index 00000000..60b65208 --- /dev/null +++ b/boot/authorization/src/main/java/com/plate/authorization/core/AuthorizationConsent.java @@ -0,0 +1,24 @@ +package com.plate.authorization.core; + +import jakarta.persistence.*; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Alex bob(Alex Bob) + */ +@Data +@Entity +@Table(name = "oauth2_authorization_consent") +public class AuthorizationConsent implements Serializable{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String registeredClientId; + private String principalName; + @Column(length = 1000) + private String authorities; + +} \ No newline at end of file diff --git a/boot/authorization/src/main/java/com/plate/authorization/core/Client.java b/boot/authorization/src/main/java/com/plate/authorization/core/Client.java new file mode 100644 index 00000000..1318bf63 --- /dev/null +++ b/boot/authorization/src/main/java/com/plate/authorization/core/Client.java @@ -0,0 +1,52 @@ +package com.plate.authorization.core; + + +import jakarta.persistence.*; +import lombok.Data; + +import java.io.Serializable; +import java.time.Instant; + +/** + * @author Alex bob(Alex Bob) + */ +@Data +@Entity +@Table(name = "oauth2_client") +public class Client implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String clientId; + + private Instant clientIdIssuedAt; + + private String clientSecret; + + private Instant clientSecretExpiresAt; + + private String clientName; + + @Column(length = 1000) + private String clientAuthenticationMethods; + + @Column(length = 1000) + private String authorizationGrantTypes; + + @Column(length = 1000) + private String redirectUris; + + @Column(length = 1000) + private String postLogoutRedirectUris; + + @Column(length = 1000) + private String scopes; + + @Column(length = 2000) + private String clientSettings; + + @Column(length = 2000) + private String tokenSettings; +} \ No newline at end of file diff --git a/boot/authorization/src/main/resources/application-local.yml b/boot/authorization/src/main/resources/application-local.yml new file mode 100644 index 00000000..1ea9249f --- /dev/null +++ b/boot/authorization/src/main/resources/application-local.yml @@ -0,0 +1,22 @@ +logging: + register-shutdown-hook: true + level: + web: debug + com.platform.boot.*: debug + org.springframework.jdbc: DEBUG + +server.port: 9000 + +spring: + application.name: plate + sql.init: + mode: always + platform: postgres + encoding: utf-8 + datasource: + url: jdbc:postgresql://192.168.1.2:5432/plate?fetchSize=2000 + username: farmer + password: q1w2e3.. + data.redis: + host: 192.168.1.2 + repositories.enabled: false \ No newline at end of file diff --git a/boot/authorization/src/main/resources/application.yml b/boot/authorization/src/main/resources/application.yml index 905db5e3..9da81ea8 100644 --- a/boot/authorization/src/main/resources/application.yml +++ b/boot/authorization/src/main/resources/application.yml @@ -5,7 +5,7 @@ server: spring: threads.virtual.enabled: true - #main.keep-alive: true + main.keep-alive: true application.name: authorization mvc.format: time: "HH:mm:ss" @@ -22,5 +22,47 @@ spring: type: redis redis: key-prefix: "authorization:caches:" - time-to-live: 300s - enable-statistics: true \ No newline at end of file + time-to-live: "300s" + enable-statistics: true + jpa: + open-in-view: true + show-sql: true + security: + user: + name: "admin" + password: "{noop}admin" + oauth2: + authorizationserver: + client: + my-client-1: + registration: + client-id: "abcd" + client-secret: "{noop}secret1" + client-authentication-methods: + - "client_secret_basic" + authorization-grant-types: + - "authorization_code" + - "refresh_token" + redirect-uris: + - "https://my-client-1.com/login/oauth2/code/abcd" + - "https://my-client-1.com/authorized" + scopes: + - "openid" + - "profile" + - "email" + - "phone" + - "address" + require-authorization-consent: true + my-client-2: + registration: + client-id: "efgh" + client-secret: "{noop}secret2" + client-authentication-methods: + - "client_secret_jwt" + authorization-grant-types: + - "client_credentials" + scopes: + - "user.read" + - "user.write" + jwk-set-uri: "https://my-client-2.com/jwks" + token-endpoint-authentication-signing-algorithm: "RS256" \ No newline at end of file diff --git a/boot/authorization/src/main/resources/data-postgres.sql b/boot/authorization/src/main/resources/data-postgres.sql deleted file mode 100644 index 8761b6d4..00000000 --- a/boot/authorization/src/main/resources/data-postgres.sql +++ /dev/null @@ -1,40 +0,0 @@ -insert into se_users(code, username, password, name, creator, updater) -values ('U1000', 'admin', - '{pbkdf2}7d8a68bc5d507bd19bc153ff10bcdef66f5a5f3d0c1ab2438630e50b5c65894bccc2c7e4404c5afa', - '系统超级管理员', 'U1000', 'U1000'); - -insert into se_authorities(code, user_code, authority, creator, updater) -values ('UA1000', 'U1000', 'ROLE_SYSTEM_ADMINISTRATORS', 'U1000', 'U1000'), - ('UA1001', 'U1000', 'users:read', 'U1000', 'U1000'), - ('UA1002', 'U1000', 'users:write', 'U1000', 'U1000'), - ('UA1003', 'U1000', 'users:delete', 'U1000', 'U1000'); - -insert into se_groups(code, name, creator, updater) -values ('G1000', '系统管理员', 'U1000', 'U1000'); - -insert into se_group_members(code, group_code, user_code, creator, updater) -values ('GM1000', 'G1000', 'U1000', 'U1000', 'U1000'); - -insert into se_group_authorities(code, group_code, authority, creator, updater) -values ('GA1000', 'G1000', 'ROLE_ADMINISTRATORS', 'U1000', 'U1000'), - ('GA1001', 'U1000', 'users:read', 'U1000', 'U1000'), - ('GA1002', 'U1000', 'users:write', 'U1000', 'U1000'); - - -/********Init menus****************/ -insert into se_menus(code, type, authority, name, path, creator, updater, extend) -values ('M1000', 'FOLDER', 'ROLE_FOLDER_SYSTEM', '系统管理', '', 'U1000', 'U1000', '{ - "icons": "settings" -}'); -insert into se_menus(code, pcode, type, authority, name, path, creator, updater, extend) -values ('M1001', 'M1000', 'MENU', 'ROLE_MENU_SYSTEM_USERS', '用户管理', '/system/users', 'U1000', 'U1000', '{ - "icons": "lock" -}'); -insert into se_menus(code, pcode, type, authority, name, path, creator, updater, extend) -values ('M1002', 'M1000', 'MENU', 'ROLE_MENU_SYSTEM_GROUPS', '角色管理', '/system/groups', 'U1000', 'U1000', '{ - "icons": "users" -}'); -insert into se_menus(code, pcode, type, authority, name, path, creator, updater, extend) -values ('M1003', 'M1000', 'MENU', 'ROLE_MENU_SYSTEM_MENUS', '菜单管理', '/system/menus', 'U1000', 'U1000', '{ - "icons": "menu-2" -}'); \ No newline at end of file diff --git a/boot/authorization/src/main/resources/schema-postgres.sql b/boot/authorization/src/main/resources/schema-postgres.sql index 8728a607..b1847f87 100644 --- a/boot/authorization/src/main/resources/schema-postgres.sql +++ b/boot/authorization/src/main/resources/schema-postgres.sql @@ -1,179 +1,68 @@ -drop table if exists oauth2_authorized_client; -create table oauth2_authorized_client -( - client_registration_id varchar(100) not null, - principal_name varchar(200) not null, - access_token_type varchar(100) not null, - access_token_value bytea not null, - access_token_issued_at timestamp not null, - access_token_expires_at timestamp not null, - access_token_scopes varchar(1000) default null, - refresh_token_value bytea default null, - refresh_token_issued_at timestamp default null, - created_at timestamp default current_timestamp not null, - primary key (client_registration_id, principal_name) -); - -drop table if exists se_users; -create table if not exists se_users -( - id serial8 primary key, - code varchar(64) not null unique, - tenant_code varchar(64) not null default '0', - username varchar(256) not null unique, - password text not null, - disabled boolean not null default false, - account_expired boolean not null default false, - account_locked boolean not null default false, - credentials_expired boolean not null default false, - name varchar(512), - email varchar(512), - phone varchar(32), - avatar text, - bio text, - extend jsonb, - creator varchar(64), - updater varchar(64), - login_time timestamp default current_timestamp, - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp -); -create index se_users_tu_idx on se_users (tenant_code, username); -create index se_users_extend_gin_idx on se_users using gin (extend); -comment on table se_users is '用户表'; - -drop table if exists se_authorities; -create table if not exists se_authorities -( - id serial8 primary key, - code varchar(64) not null unique, - user_code varchar(64) not null, - authority varchar(512) not null, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp, - unique (user_code, authority) -); -comment on table se_authorities is '用户权限表'; - -drop table if exists se_groups; -create table if not exists se_groups -( - id serial8 primary key, - code varchar(64) not null unique, - tenant_code varchar(64) not null default '0', - name varchar(512) not null, - extend jsonb, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp -); -create index se_groups_tn_idx on se_groups (tenant_code, name); -create index se_groups_extend_gin_idx on se_groups using gin (extend); -comment on table se_groups is '角色表'; +-- Drop tables if they exist (ensures clean setup) +drop table if exists oauth2_client; +drop table if exists oauth2_authorization; +drop table if exists oauth2_authorization_consent; -drop table if exists se_group_authorities; -create table if not exists se_group_authorities +create table oauth2_client ( - id serial8 primary key, - code varchar(64) not null unique, - group_code varchar(64) not null, - authority varchar(512) not null, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp, - unique (group_code, authority) + id SERIAL primary key, + client_id VARCHAR(255) not null, + client_id_issued_at TIMESTAMP not null default current_timestamp, + client_secret VARCHAR(255) default null, + client_secret_expires_at TIMESTAMP default null, + client_name VARCHAR(255) not null, + client_authentication_methods VARCHAR(1000) not null, + authorization_grant_types VARCHAR(1000) not null, + redirect_uris VARCHAR(1000) default null, + post_logout_redirect_uris VARCHAR(1000) default null, + scopes VARCHAR(1000) not null, + client_settings VARCHAR(2000) not null, + token_settings VARCHAR(2000) not null ); -comment on table se_group_authorities is '角色权限表'; -drop table if exists se_group_members; -create table if not exists se_group_members +create table oauth2_authorization ( - id serial8 primary key, - code varchar(64) not null unique, - group_code varchar(64) not null, - user_code varchar(64) not null, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp, - unique (group_code, user_code) + id SERIAL primary key, + registered_client_id VARCHAR(255) not null, + principal_name VARCHAR(255) not null, + authorization_grant_type VARCHAR(255) not null, + authorized_scopes VARCHAR(1000) default null, + attributes VARCHAR(4000) default null, + state VARCHAR(500) default null, + authorization_code_value VARCHAR(4000) default null, + authorization_code_issued_at TIMESTAMP default null, + authorization_code_expires_at TIMESTAMP default null, + authorization_code_metadata VARCHAR(2000) default null, + access_token_value VARCHAR(4000) default null, + access_token_issued_at TIMESTAMP default null, + access_token_expires_at TIMESTAMP default null, + access_token_metadata VARCHAR(2000) default null, + access_token_type VARCHAR(255) default null, + access_token_scopes VARCHAR(1000) default null, + refresh_token_value VARCHAR(4000) default null, + refresh_token_issued_at TIMESTAMP default null, + refresh_token_expires_at TIMESTAMP default null, + refresh_token_metadata VARCHAR(2000) default null, + oidc_id_token_value VARCHAR(4000) default null, + oidc_id_token_issued_at TIMESTAMP default null, + oidc_id_token_expires_at TIMESTAMP default null, + oidc_id_token_metadata VARCHAR(2000) default null, + oidc_id_token_claims VARCHAR(2000) default null, + user_code_value VARCHAR(4000) default null, + user_code_issued_at TIMESTAMP default null, + user_code_expires_at TIMESTAMP default null, + user_code_metadata VARCHAR(2000) default null, + device_code_value VARCHAR(4000) default null, + device_code_issued_at TIMESTAMP default null, + device_code_expires_at TIMESTAMP default null, + device_code_metadata VARCHAR(2000) default null ); -comment on table se_group_members is '角色用户关系表'; -drop table if exists se_tenants; -create table if not exists se_tenants +create table oauth2_authorization_consent ( - id serial primary key, - code varchar(64) not null unique, - name varchar(512) not null, - description text, - extend jsonb, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp -); -create index se_tenants_name_idx on se_tenants (name); -create index se_tenants_extend_gin_idx on se_tenants using gin (extend); -comment on table se_tenants is '租户表'; - -drop table if exists se_tenant_members; -create table if not exists se_tenant_members -( - id serial8 primary key, - code varchar(64) not null unique, - tenant_code varchar(64) not null, - user_code varchar(64) not null, - enabled boolean not null default true, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp, - unique (tenant_code, user_code) -); -comment on table se_tenant_members is '租户用户关系表'; - -drop table if exists se_menus; -create table if not exists se_menus -( - id serial8 primary key, - code varchar(64) not null unique, - pcode varchar(64) not null default '0', - tenant_code varchar(64) not null default '0', - type varchar(20) not null default 'MENU', - authority varchar(512) not null unique, - name varchar(512) not null, - path text, - sort int default 0, - extend jsonb, - creator varchar(64), - updater varchar(64), - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp -); -create index se_menus_pttn_idx on se_menus (pcode, tenant_code, type, name); -create index se_menus_extend_gin_idx on se_menus using gin (extend); -comment on table se_menus is '菜单权限表'; - -drop table if exists se_loggers; -create table if not exists se_loggers -( - id serial8 primary key, - code varchar(64) not null unique, - tenant_code varchar(64) not null default '0', - prefix varchar(64), - operator varchar(64), - status varchar(64), - method varchar(64), - url text, - context jsonb, - created_time timestamp default current_timestamp, - updated_time timestamp default current_timestamp -); -create index se_loggers_tposm_idx on se_loggers (tenant_code, prefix, operator, status, method); -create index se_loggers_extend_gin_idx on se_loggers using gin (context); -comment on table se_loggers is '操作日志表'; \ No newline at end of file + id SERIAL primary key, + registered_client_id VARCHAR(255) not null, + principal_name VARCHAR(255) not null, + authorities VARCHAR(1000) not null, + unique (registered_client_id, principal_name) +); \ No newline at end of file diff --git a/boot/authorization/src/main/resources/static/index.html b/boot/authorization/src/main/resources/static/index.html new file mode 100644 index 00000000..4a355266 --- /dev/null +++ b/boot/authorization/src/main/resources/static/index.html @@ -0,0 +1,10 @@ + + + + + Title + + +

index

+ + \ No newline at end of file