使用框架 重构
This commit is contained in:
53
pom.xml
53
pom.xml
@@ -32,22 +32,26 @@
|
||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<spring.boot.version>3.2.0</spring.boot.version>
|
||||
<slf4j.version>2.0.9</slf4j.version>
|
||||
<spring.boot.version>3.5.3</spring.boot.version>
|
||||
|
||||
<arrokoth.version>1.1.0.RELEASE</arrokoth.version>
|
||||
<arrokoth.bom.version>1.1.0.RELEASE</arrokoth.bom.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.arrokoth.framework.boot</groupId>
|
||||
<artifactId>arrokoth-framework-starter</artifactId>
|
||||
<version>${arrokoth.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 通用认证模块 -->
|
||||
<dependency>
|
||||
<groupId>com.arrokoth.framework</groupId>
|
||||
<artifactId>basic-authorization-server</artifactId>
|
||||
<version>1.0.1-RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -122,8 +126,21 @@
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.arrokoth.framework.boot</groupId>
|
||||
<artifactId>arrokoth-framework-springboot-dependencies</artifactId>
|
||||
<version>${arrokoth.bom.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
<build>
|
||||
<directory>${project.basedir}/target</directory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -139,7 +156,8 @@
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build-info</goal>
|
||||
<goal>build-info</goal> <!-- 生成构建信息 -->
|
||||
<goal>repackage</goal> <!-- 默认 goal,必须保留 -->
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
@@ -150,20 +168,27 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<parameters>true</parameters>
|
||||
<parameters>true</parameters> <!-- 支持获取方法参数名 -->
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<fork>true</fork>
|
||||
<verbose>true</verbose>
|
||||
<encoding>UTF-8</encoding>
|
||||
<showWarnings>false</showWarnings>
|
||||
<fork>true</fork> <!-- 使用独立 JVM 编译 -->
|
||||
<verbose>true</verbose> <!-- 输出详细编译信息 -->
|
||||
<encoding>UTF-8</encoding> <!-- 源码编码 -->
|
||||
<showWarnings>false</showWarnings> <!-- 不显示警告 -->
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
|
||||
<version>2.22.0</version>
|
||||
<configuration>
|
||||
<!-- 可选配置项 -->
|
||||
<failIfNoTests>false</failIfNoTests> <!-- 即使没有测试也不失败 -->
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
<include>**/*Tests.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.arrokoth.standalone.authorization;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import com.arrokoth.basic.annotation.EnableArrokothBasicModule;
|
||||
import com.arrokoth.framework.boot.annotation.EnableGracefulRestResponse;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@MapperScan("com.arrokoth.basic.mapper")
|
||||
@ComponentScan(basePackages = "com.arrokoth")
|
||||
@EnableGracefulRestResponse
|
||||
@EnableArrokothBasicModule
|
||||
@SpringBootApplication
|
||||
public class StandaloneServerApplication {
|
||||
|
||||
|
||||
@@ -12,10 +12,7 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
|
||||
@@ -76,19 +73,6 @@ public class AuthorizationServerAutoConfigurer {
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public AuthorizationServerSettings authorizationServerSettings() {
|
||||
return AuthorizationServerSettings.builder()
|
||||
.authorizationEndpoint(authorizationServerProperties.getAuthorizationEndpoint()) // 授权端点路径
|
||||
.issuer(authorizationServerProperties.getIssuer()) // 授权服务器的唯一标识符(Issuer)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(); // 仅用于演示,生产环境请使用BCryptPasswordEncoder
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.arrokoth.standalone.authorization.config;
|
||||
|
||||
import com.arrokoth.basic.properties.AuthorizationServerProperties;
|
||||
import com.arrokoth.basic.properties.SecurityWebProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
|
||||
|
||||
@Configuration
|
||||
public class OAuth2Config {
|
||||
|
||||
|
||||
@Bean
|
||||
public AuthorizationServerSettings authorizationServerSettings(AuthorizationServerProperties authorizationServerProperties,
|
||||
SecurityWebProperties securityWebProperties) {
|
||||
return AuthorizationServerSettings.builder()
|
||||
.authorizationEndpoint(authorizationServerProperties.getAuthorizationEndpoint()) // 授权端点路径
|
||||
.issuer(authorizationServerProperties.getIssuer()) // 授权服务器的唯一标识符(Issuer)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(); // 仅用于演示,生产环境请使用BCryptPasswordEncoder
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.arrokoth.standalone.authorization.config;
|
||||
|
||||
|
||||
import com.arrokoth.basic.autoconfiguration.BasicAutoConfiguration;
|
||||
import com.arrokoth.basic.properties.SecurityWebProperties;
|
||||
import com.arrokoth.standalone.authorization.filter.JwtRequestFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -27,7 +25,6 @@ import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@AutoConfigureBefore(BasicAutoConfiguration.class)
|
||||
@AllArgsConstructor
|
||||
@EnableConfigurationProperties(SecurityWebProperties.class)
|
||||
public class SecurityWebAutoConfigurer {
|
||||
@@ -55,10 +52,17 @@ public class SecurityWebAutoConfigurer {
|
||||
.loginProcessingUrl(securityWebProperties.getLoginProcessingUrl())
|
||||
.permitAll()
|
||||
)
|
||||
|
||||
|
||||
.logout(logout -> logout
|
||||
.logoutUrl(SecurityWebProperties.AXIOS_LOGOUT_PROCESSING_URL)
|
||||
.logoutSuccessUrl(securityWebProperties.getLogoutSuccessUrl())
|
||||
.invalidateHttpSession(true) // 注销时销毁 session
|
||||
.deleteCookies("JSESSIONID", "Authorization")
|
||||
.permitAll()
|
||||
);
|
||||
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
@@ -72,10 +76,10 @@ public class SecurityWebAutoConfigurer {
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
log.info("Configuring cors configuration source");
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
configuration.setExposedHeaders(List.of("Authorization")); // 允许前端访问Authorization头
|
||||
configuration.setAllowedOrigins(List.of("*")); // 替换为前端域名
|
||||
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "X-Requested-With", "accept"));
|
||||
configuration.setExposedHeaders(List.of("Authorization")); // 允许前端访问Authorization头
|
||||
configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type", "X-Requested-With", "accept", "X-XSRF-TOKEN"));
|
||||
configuration.setAllowCredentials(false);
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
|
||||
@@ -2,14 +2,24 @@ package com.arrokoth.standalone.authorization.controller;
|
||||
|
||||
import com.arrokoth.standalone.authorization.service.OAuth2ConsentService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@Lazy
|
||||
@Controller
|
||||
@RequiredArgsConstructor
|
||||
public class AuthorizationController {
|
||||
@@ -19,6 +29,7 @@ public class AuthorizationController {
|
||||
private final OAuth2ConsentService oAuth2ConsentService;
|
||||
|
||||
|
||||
|
||||
@GetMapping("/login")
|
||||
public String home() {
|
||||
return "login"; // 对应templates/login.html
|
||||
@@ -33,15 +44,71 @@ public class AuthorizationController {
|
||||
@RequestParam("state") String state,
|
||||
@RequestParam(name = "user_code", required = false) String userCode) {
|
||||
|
||||
OAuth2ConsentService.ConsentResponse viewModel = oAuth2ConsentService.getConsentDetails(principal, clientId, scope, state, userCode);
|
||||
OAuth2ConsentService.ConsentResponse viewModel = oAuth2ConsentService.getConsentDetails(principal, clientId, scope, state, principal.getName());
|
||||
|
||||
model.addAttribute("clientId", clientId);
|
||||
model.addAttribute("state", state);
|
||||
model.addAttribute("scopes", withDescription(viewModel.scopesToApprove()));
|
||||
model.addAttribute("previouslyApprovedScopes", withDescription(viewModel.previouslyApprovedScopes()));
|
||||
model.addAttribute("principalName", principal.getName());
|
||||
model.addAttribute("userCode", userCode);
|
||||
if (StringUtils.hasText(userCode)) {
|
||||
model.addAttribute("requestURI", "/oauth2/device_verification");
|
||||
} else {
|
||||
model.addAttribute("requestURI", "/oauth2/authorize");
|
||||
}
|
||||
|
||||
// model.addAttribute("clientId", viewModel.clientId());
|
||||
// model.addAttribute("state", viewModel.state());
|
||||
// model.addAttribute("scopes", viewModel.scopes());
|
||||
model.addAttribute("previouslyApprovedScopes", viewModel.previouslyApprovedScopes());
|
||||
// model.addAttribute("principalName", viewModel.principalName());
|
||||
// model.addAttribute("userCode", viewModel.userCode());
|
||||
// model.addAttribute("requestURI", viewModel.requestURI());
|
||||
return "consent";
|
||||
}
|
||||
|
||||
|
||||
private static Set<ScopeWithDescription> withDescription(Set<String> scopes) {
|
||||
Set<ScopeWithDescription> scopeWithDescriptions = new HashSet<>();
|
||||
for (String scope : scopes) {
|
||||
scopeWithDescriptions.add(new ScopeWithDescription(scope));
|
||||
|
||||
}
|
||||
return scopeWithDescriptions;
|
||||
}
|
||||
|
||||
|
||||
public static class ScopeWithDescription {
|
||||
private static final String DEFAULT_DESCRIPTION = "UNKNOWN SCOPE - We cannot provide information about this permission, use caution when granting this.";
|
||||
private static final Map<String, String> scopeDescriptions = new HashMap<>();
|
||||
|
||||
static {
|
||||
scopeDescriptions.put(
|
||||
OidcScopes.PROFILE,
|
||||
"This application will be able to read your profile information."
|
||||
);
|
||||
scopeDescriptions.put(
|
||||
"message.read",
|
||||
"This application will be able to read your message."
|
||||
);
|
||||
scopeDescriptions.put(
|
||||
"message.write",
|
||||
"This application will be able to add new messages. It will also be able to edit and delete existing messages."
|
||||
);
|
||||
scopeDescriptions.put(
|
||||
"user.read",
|
||||
"This application will be able to read your user information."
|
||||
);
|
||||
scopeDescriptions.put(
|
||||
"other.scope",
|
||||
"This is another scope example of a scope description."
|
||||
);
|
||||
}
|
||||
|
||||
public final String scope;
|
||||
public final String description;
|
||||
|
||||
ScopeWithDescription(String scope) {
|
||||
this.scope = scope;
|
||||
this.description = scopeDescriptions.getOrDefault(scope, DEFAULT_DESCRIPTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -18,12 +18,12 @@ import java.util.UUID;
|
||||
@Configuration
|
||||
public class RegisteredClientRepositoryStore {
|
||||
|
||||
|
||||
@Bean
|
||||
public RegisteredClientRepository registeredClientRepository() {
|
||||
|
||||
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
|
||||
RegisteredClient oidcClient = RegisteredClient.withId(UUID.randomUUID().toString())
|
||||
|
||||
.clientId("messaging-client")
|
||||
.clientSecret(bCryptPasswordEncoder.encode("secret"))
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
@@ -31,6 +31,7 @@ public class RegisteredClientRepositoryStore {
|
||||
.authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
|
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
|
||||
.redirectUri("http://127.0.0.1:8091/login/oauth2/code/messaging-client-oidc")
|
||||
.postLogoutRedirectUri("http://127.0.0.1:8080/logged-out")
|
||||
.scope(OidcScopes.OPENID)
|
||||
.scope(OidcScopes.PROFILE)
|
||||
.scope("message.read")
|
||||
|
||||
@@ -1,6 +1,32 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
arrokoth:
|
||||
authorization:
|
||||
server:
|
||||
consent-page: /oauth2/consent
|
||||
authorization-endpoint: /oauth2/authorize
|
||||
issuer: http://127.0.0.1
|
||||
security:
|
||||
web:
|
||||
swagger-ui: false
|
||||
login-page: /login
|
||||
logout-success-url: /login?logout
|
||||
permit-urls:
|
||||
- /home/login
|
||||
- /login/oauth2/**
|
||||
- /oauth2/token
|
||||
|
||||
# RestApi增强配置
|
||||
graceful-rest-response:
|
||||
enabled: true
|
||||
banner: true
|
||||
print-exception-in-global-advice: true
|
||||
origin-exception-using-detail-message: false
|
||||
exclude-urls:
|
||||
- "/swagger-resources"
|
||||
- "/v3/api-docs/*"
|
||||
- "/v2/api-docs"
|
||||
|
||||
|
||||
spring:
|
||||
@@ -27,19 +53,8 @@ spring:
|
||||
max-wait: 2000ms # 获取连接最大等待时间
|
||||
|
||||
|
||||
arrokoth:
|
||||
authorization:
|
||||
server:
|
||||
consent-page: /oauth2/consent
|
||||
authorization-endpoint: /oauth2/authorize
|
||||
issuer: https://www.arrokoth-info.com
|
||||
security:
|
||||
web:
|
||||
swagger-ui: false
|
||||
login-page: /login
|
||||
logout-success-url: /login?logout
|
||||
permit-urls:
|
||||
- /home/login
|
||||
|
||||
|
||||
|
||||
|
||||
logging:
|
||||
|
||||
Reference in New Issue
Block a user