javax.security完整教程:JAAS认证、权限控制与加密实现

2024-06-21 李腾 50 次阅读 0 次点赞
javax.security是Java安全体系的核心包,提供完整的身份认证、访问控制和加密功能。本文通过5个实战示例详细演示JAAS认证流程、安全权限检查、RSA密钥加解密、自定义LoginModule实现以及JAAS配置文件使用方法。每个示例都包含完整可运行的Java代码,帮助开发者深入理解Java安全机制并快速应用到实际项目中。

javax.security 是 Java 安全框架的核心包,提供了身份认证、访问控制、加密等安全功能。下面详细介绍其主要组件并提供示例代码:

主要组件概览

1. 认证相关

AuthPermission - 认证权限

LoginContext - 登录上下文

Subject - 主体(用户身份)

2. 访问控制

Policy - 安全策略

ProtectionDomain - 保护域

3. 加密相关

Key - 密钥接口

PrivateKey, PublicKey - 公私钥

核心示例代码

1. JAAS 认证示例

import javax.security.auth.*;
import javax.security.auth.login.*;
import javax.security.auth.callback.*;
import java.security.Principal;
import java.util.Set;

public class JAASExample {
    
    // 自定义回调处理器
    static class SimpleCallbackHandler implements CallbackHandler {
        private String username;
        private char[] password;
        
        public SimpleCallbackHandler(String username, String password) {
            this.username = username;
            this.password = password.toCharArray();
        }
        
        @Override
        public void handle(Callback[] callbacks) {
            for (Callback callback : callbacks) {
                if (callback instanceof NameCallback) {
                    ((NameCallback) callback).setName(username);
                } else if (callback instanceof PasswordCallback) {
                    ((PasswordCallback) callback).setPassword(password);
                }
            }
        }
    }
    
    public static void main(String[] args) {
        try {
            // 创建登录上下文
            LoginContext loginContext = new LoginContext(
                "SampleLogin", 
                new SimpleCallbackHandler("testuser", "testpass")
            );
            
            // 执行登录
            loginContext.login();
            System.out.println("认证成功!");
            
            // 获取认证主体
            Subject subject = loginContext.getSubject();
            Set<Principal> principals = subject.getPrincipals();
            
            System.out.println("认证主体:");
            for (Principal principal : principals) {
                System.out.println(" - " + principal.getName());
            }
            
            // 执行特权操作
            Subject.doAs(subject, new PrivilegedAction<Void>() {
                public Void run() {
                    // 这里可以执行需要权限的操作
                    System.out.println("执行特权操作...");
                    return null;
                }
            });
            
            // 注销
            loginContext.logout();
            
        } catch (LoginException e) {
            System.err.println("认证失败: " + e.getMessage());
        }
    }
}

2. 安全策略和权限检查

import java.security.*;
import javax.security.auth.*;

public class SecurityPolicyExample {
    
    public static void main(String[] args) {
        // 启用安全管理器
        System.setSecurityManager(new SecurityManager());
        
        try {
            // 检查文件读取权限
            Permission permission = new java.io.FilePermission("/tmp/test.txt", "read");
            AccessController.checkPermission(permission);
            System.out.println("具有文件读取权限");
            
        } catch (AccessControlException e) {
            System.err.println("权限不足: " + e.getMessage());
        }
        
        // 使用 doPrivileged 执行特权代码
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                // 这里执行需要特权的操作
                System.out.println("执行特权操作");
                return null;
            }
        });
    }
}

3. 密钥管理示例

import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class KeyManagementExample {
    
    public static void main(String[] args) throws Exception {
        // 生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        KeyPair keyPair = keyGen.generateKeyPair();
        
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        System.out.println("公钥算法: " + publicKey.getAlgorithm());
        System.out.println("私钥格式: " + privateKey.getFormat());
        
        // 使用密钥进行加密
        Cipher cipher = Cipher.getInstance("RSA");
        String originalText = "Hello, Security!";
        
        // 公钥加密
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encrypted = cipher.doFinal(originalText.getBytes());
        System.out.println("加密后长度: " + encrypted.length);
        
        // 私钥解密
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decrypted = cipher.doFinal(encrypted);
        System.out.println("解密文本: " + new String(decrypted));
    }
}

4. 自定义 LoginModule

import javax.security.auth.*;
import javax.security.auth.spi.*;
import javax.security.auth.callback.*;
import java.util.*;
import java.io.IOException;

public class SimpleLoginModule implements LoginModule {
    private Subject subject;
    private CallbackHandler callbackHandler;
    private Map<String, ?> sharedState;
    private Map<String, ?> options;
    
    private boolean loginSucceeded = false;
    private String username;
    
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler,
                          Map<String, ?> sharedState, Map<String, ?> options) {
        this.subject = subject;
        this.callbackHandler = callbackHandler;
        this.sharedState = sharedState;
        this.options = options;
    }
    
    @Override
    public boolean login() throws LoginException {
        if (callbackHandler == null) {
            throw new LoginException("No CallbackHandler available");
        }
        
        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("用户名: ");
        callbacks[1] = new PasswordCallback("密码: ", false);
        
        try {
            callbackHandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            char[] password = ((PasswordCallback) callbacks[1]).getPassword();
            
            // 简单的用户名密码验证
            if ("admin".equals(username) && "password".equals(new String(password))) {
                loginSucceeded = true;
                return true;
            } else {
                loginSucceeded = false;
                throw new FailedLoginException("认证失败");
            }
            
        } catch (IOException | UnsupportedCallbackException e) {
            throw new LoginException(e.toString());
        }
    }
    
    @Override
    public boolean commit() throws LoginException {
        if (!loginSucceeded) {
            return false;
        }
        
        // 将主体添加到 Subject
        subject.getPrincipals().add(new SimplePrincipal(username));
        return true;
    }
    
    @Override
    public boolean abort() throws LoginException {
        if (!loginSucceeded) {
            return false;
        }
        logout();
        return true;
    }
    
    @Override
    public boolean logout() throws LoginException {
        subject.getPrincipals().remove(new SimplePrincipal(username));
        loginSucceeded = false;
        username = null;
        return true;
    }
    
    // 简单的主体实现
    static class SimplePrincipal implements Principal {
        private String name;
        
        public SimplePrincipal(String name) {
            this.name = name;
        }
        
        @Override
        public String getName() {
            return name;
        }
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (!(obj instanceof SimplePrincipal)) return false;
            return name.equals(((SimplePrincipal) obj).name);
        }
        
        @Override
        public int hashCode() {
            return name.hashCode();
        }
    }
}

5. JAAS 配置文件示例

创建 jaas.config 文件:

SampleLogin {
    SimpleLoginModule required debug=true;
};

运行程序时指定配置文件:

java -Djava.security.auth.login.config=jaas.config JAASExample

主要特点

1、可插拔认证 - 通过 LoginModule 实现灵活认证

2、基于主体的授权 - Subject 包含用户身份和凭证

3、权限检查 - 通过 AccessController 进行细粒度权限控制

4、策略管理 - 可配置的安全策略文件

本文由人工编写,AI优化,转载请注明原文地址: Java安全框架javax.security使用指南:认证授权与加密实战

评论 (1)

登录后发表评论
行者无疆2025-11-13 09:04:49
这篇指南太实用了!示例代码很清晰,帮我解决了JAAS认证配置的难题。感谢作者的分享!