You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非Spring Boot/Web的JavaFX桌面应用集成Spring Security方案咨询

在非Spring Boot的JavaFX桌面应用中集成Spring Security

1. 引入核心依赖

因为不是Spring Boot/Web应用,仅需引入Spring Security核心模块和Spring上下文依赖(用于Bean管理),以Maven为例:

<dependencies>
    <!-- Spring Security 核心 -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>5.7.11</version> <!-- 选择合适的稳定版本 -->
    </dependency>
    <!-- Spring 上下文 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.29</version>
    </dependency>
</dependencies>

2. 初始化Spring容器与Security配置

手动创建Spring配置类,定义Security核心Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true) // 开启方法级权限注解支持
public class SecurityConfig {

    // 密码编码器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 用户信息服务(示例用内存存储,实际可替换为数据库查询)
    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("admin")
                .password(passwordEncoder().encode("admin123"))
                .roles("ADMIN")
                .build());
        manager.createUser(User.withUsername("user")
                .password(passwordEncoder().encode("user123"))
                .roles("USER")
                .build());
        return manager;
    }

    // 认证管理器
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
        return auth.build();
    }
}

在JavaFX应用启动时初始化Spring容器:

import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp extends Application {
    private static AnnotationConfigApplicationContext springContext;

    @Override
    public void init() throws Exception {
        // 初始化Spring容器
        springContext = new AnnotationConfigApplicationContext(SecurityConfig.class);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        // 加载登录界面
        LoginController loginController = springContext.getBean(LoginController.class);
        loginController.showLoginWindow(primaryStage);
    }

    @Override
    public void stop() throws Exception {
        // 关闭Spring容器
        springContext.close();
    }

    public static AnnotationConfigApplicationContext getSpringContext() {
        return springContext;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

3. 实现登录认证逻辑

在JavaFX登录控制器中,注入AuthenticationManager处理登录请求:

import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;

public class LoginController {
    private final AuthenticationManager authenticationManager;

    // 构造注入AuthenticationManager(Spring自动完成)
    public LoginController(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }

    @FXML
    private TextField usernameField;
    @FXML
    private PasswordField passwordField;

    @FXML
    private void handleLogin() {
        String username = usernameField.getText();
        String password = passwordField.getText();

        try {
            // 执行认证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password)
            );
            // 将认证信息存入SecurityContext
            SecurityContextHolder.getContext().setAuthentication(authentication);
            // 登录成功跳转主界面
            openMainWindow();
            closeLoginWindow();
        } catch (AuthenticationException e) {
            // 认证失败提示错误
            showError("登录失败:" + e.getMessage());
        }
    }

    // 界面跳转辅助方法,根据实际FXML调整
    private void openMainWindow() {
        // 加载主界面逻辑
    }

    private void closeLoginWindow() {
        ((Stage) usernameField.getScene().getWindow()).close();
    }

    private void showError(String message) {
        // 弹出错误提示
    }
}

4. 实现授权控制

方法级授权

在业务Bean上使用@PreAuthorize注解控制方法调用权限:

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    // 仅ADMIN角色可调用
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteUser(String userId) {
        // 删除用户逻辑
    }

    // USER或ADMIN角色均可调用
    @PreAuthorize("hasAnyRole('USER', 'ADMIN')")
    public void viewUser(String userId) {
        // 查看用户逻辑
    }
}

UI层面权限控制

在JavaFX控制器中,根据当前用户权限动态显示/隐藏控件:

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

public class MainController {
    @FXML
    private Button deleteUserBtn;

    @FXML
    public void initialize() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        // 判断是否拥有ADMIN权限,无权限则隐藏删除按钮
        boolean isAdmin = auth.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"));
        deleteUserBtn.setVisible(isAdmin);
    }
}

5. 会话状态维护

  • 应用退出时清除SecurityContext:
@Override
public void stop() throws Exception {
    SecurityContextHolder.clearContext();
    springContext.close();
}
  • 页面切换时,可通过SecurityContextHolder.getContext().getAuthentication()获取当前用户信息,重复权限校验逻辑。

内容的提问来源于stack exchange,提问作者Ali Akbar Ahmadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:05:00