`

转载:《JAAS》

    博客分类:
  • Java
阅读更多
转载自:http://blog.csdn.net/tancaiyi/article/details/3971585

声明:本人转载只为分享,如涉及商业版权纠纷,请及时与本人联系,必将立即删除,造成不便,还望见谅,谢谢。

Java平台是创建企业应用程序的普遍选择。它所以受欢迎,主要原因之一是在创建Java语言时充分考虑了安全性,而且市场上也普遍认为Java是一种"安全的"语言。Java平台在两个层次上提供安全性:语言层次安全性和企业层次安全性。
1.语言层次安全性
最初的Java(JDK1.2)平台采用沙箱安全模型,基本安全模型由三部分来承担,这三部分构成Java运行环境的三个安全组件,分别是:类加载器,文件校验器,安全管理器
1.1类加载器
类加载器负责从特定位置加载类,类加载器是JVM的看门人,控制着哪些代码被加载或被拒绝,类加载器首先进行安全性检查,它往往从以下几个方面去检查,装入的字节码是否生成指针,装入的字节码是否违反访问限制,装入的字节码是否把对象当作它们本身来访问,它在确保执行代码的安全性方面至关重要。
1.2类文件校验器的校验
类文件校验器负责检查那些无法执行的明显有破坏性的操作,类文件校验器执行的一些检查通常有:变量要在使用之前进行初始化;方法调用和对象引用类型之间要匹配;没有违反访问私有数据和方法的规则;对本地变量的访问都在运行时堆栈内;运行时堆栈是否溢出.如果以上检查中任何一条没有通过,就认为该类遭到了破坏,不被加载。
1.3安全管理器
一旦某个类被类加载器加载到虚拟机中,并由类文件校验器检查过之后,JAVA的第三种安全机制安全管理器就会启动,安全管理器是一个负责控制某个操作是否允许执行的类,安全管理器负责检查包括以下几个方面的操作:当前线程是否能创建一个新的类加载器;当前线程是否能终止JVM的运行;某个类是否能访问另一个类的成员;当前线程是否能访问本地文件;当前线程是否能打开到达外部记住的socket连接;某个类是否能启动打印作业;某个类是否能访问系统剪贴板;某个类是否能访问AWT事件队列;当前线程是否可被信任以打开一顶层窗口。
尽管Java安全的支柱类加载器、类文件校验器、安全管理器每一个都有独特的功能,但它们又相互依赖、相辅相承。共同保证了Java语言的安全性。
2.企业层次的安全特性
即是构建安全的J2EE应用。Java平台在提供语言安全性的同时还提供其他API功能,为企业应用程序提供一个总体的安全性解决方案。下面将介绍几种方案。
2.1 Java加密扩展(JCE)
JCE是一组包,为加密、密钥生成、密钥协商和消息身份验证代码(MAC)算法提供一种框架和实现。JCE支持多种类型的加密,包括对称的、非对称的、块和流密码。在JDK 1.4之前,JCE是一个可选的包,现在它已经成为Java平台的一个标准组成部分。
2.2 Java安全套接字扩展(JSSE)
JSSE是支持安全的Internet通信的一组包。它是实现了SSL和传输层安全(TLS)协议的JAVA技术。它包括用于数据加密、服务器身份验证、消息完整性和可选的客户端身份验证的诸多功能。JSSE已被集成到JDK 1.4以上版本的平台中。
2.3 Java身份验证和授权规范(JAAS)
JAAS通过对运行程序的用户的进行验证,从而达到保护系统的目的。JAAS主要由两个部件构成,认证和授权,JAAS通过一个配置文件来定义认证机制。认证模块是基于可插的认证模块而设计的,它可以运行在客户端和服务器端,授权模块的设计是一个变化的过程,为了对资源的访问请求进行授权,首先需要应用程序认证请求的资源,subject术语来表示请求的资源,用java.security.auth.Subject类来表示subject。subject一旦通过了认证,就会和身份和主体想关联。在JAAS中将主体表示为javax.security.Principal对象,一个subject可能包含多个主题,除了和主题相关联外,subject还可能拥有与安全相关的属性或证书,证书是用户的数据,它包含这样的认证信息即认证subject所拥有的其他服务的信息。基于J2EE的分布式应用程序使用
JAAS一般有两种情况:第一种情况,一个单独的应用系统与一个远程的EJB系统连接,用户必须向应用系统提供证明身份的信息或应用系统向文件和其它的系统来检索可证明身份的信息。这个单独的应用系统将在调用EJB组件之前使用JAAS来验证用户,由应用服务器完成验证的任务。只有当用户通过JAAS的验证之后,客户端程序才可被信任地调用EJB方法。第二种情况,基于Web浏览器的客户端程序连接到Servlet/JSP层,客户端用户将向Servlet/JSP层提供证明身份的信息,而Servlet/JSP层可以采用JAAS验证用户。Web客户端一般可以采
用基本验证、基于表格的验证、摘要验证、证书验证等方式来提供证明身份的信息。这种支持选择不同认证方法的灵活性有助于支持在管理员层实施更为复杂的安全策略,而不是在编程层上去实现。一旦客户端通过应用服务器认证,安全上下文环境能被传播到EJB层。在应用程序中使用JAAS验证通常会涉及到以下几个步骤:
1.创建一个LoginContext的实例。并传递LoginModule配置
文件程序段和CallbackHandler的名称。
2.为了能够获得和处理验证信息,将一个CallbackHandler
对象作为参数传送给LoginContext。
3.通过调用LoginContext的login()方法来进行验证。
4.通过使用login()方法返回的Subject对象实现一些特殊
的功能(假设登录成功)。
举个例子:
LoginModel是jaas的一个核心接口,她负责实施用户认证。同时暴漏了initialize(),login(),commit(),abort(),logout()方法。





package sample;

import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* @author worldheart
*
*/
public class ScreenContentLoginModule implements LoginModule {
   
    protected static final Log log = LogFactory.getLog(ScreenContentLoginModule.class);
   
    private Subject subject;
    private UsernamePasswordPrincipal principal;
    private CallbackHandler callbackhandler;
   
    public ScreenContentLoginModule() {
        log.info("ScreenContentLoginModule()................");
    }
//在初始化LoginModel后,LoginContext会调用这一方法,从而完成当前LoginModel的初始化工作
    public void initialize(Subject subject, CallbackHandler
            callbackhandler, Map state, Map options) {
        log.info("进入initialize()................");
        this.principal = null;
        this.subject = subject;
        this.callbackhandler = callbackhandler;
    }
//用户阶段1,并认证subject的方法,它可能会收集用户的凭证,比如用户名,密码,并将认证结果存储到LoginModel的实例中
    public boolean login() throws LoginException {
        log.info("进入login()................");
       
        Callback callbacks[] = new Callback[2];
        callbacks[0] = new NameCallback("您的登录名:");
        callbacks[1] = new PasswordCallback("您的密码:", false);
       
        String username = null;
        String password = null;
       
        try {
            this.callbackhandler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            password = new String(((PasswordCallback) callbacks[1]).getPassword());
        } catch (java.io.IOException ioe) {
            throw new LoginException(ioe.toString());
        } catch (UnsupportedCallbackException ce) {
            throw new LoginException(ce.getCallback().toString());
        }
       
        if (username.equals("marissa") || username.equals("scott")) {
            this.principal = new UsernamePasswordPrincipal(username,password);
            return true;
        } else {
            return false;
        }       
    }
//表明认证操作成功,会获得阶段1(login())的认证结果,并将这一结果填充到subject中
    public boolean commit() throws LoginException {
        log.info("进入commit()................");
        if(this.principal == null)
            return false;
        this.subject.getPrincipals().add(this.principal);
        return true;
    }
//认证操作失败
    public boolean abort() throws LoginException {
        log.info("进入abort()................");
        if(this.principal == null)
            return false;
        this.principal = null;
        return true;
    }
//完成subject的销毁工作
    public boolean logout() throws LoginException {
        log.info("进入logout()................");
        if(this.principal == null)
            return false;
        this.subject.getPrincipals().remove(principal);
        this.principal = null;
        return true;
    }
   
}

下面是UsernamePasswordCallbackhandler类:
package sample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* @author worldheart
*
*/
public class UsernamePasswordCallbackHandler implements CallbackHandler {

    protected static final Log log = LogFactory.getLog(UsernamePasswordCallbackHandler.class);

    public void handle(Callback callbacks[]) throws IOException, UnsupportedCallbackException {
        log.info("进入handle()........................");
        for (Callback cb: callbacks) {
            if (cb instanceof NameCallback) {
                NameCallback nc = (NameCallback) cb;
                log.info(nc.getPrompt());
                //采集用户名
                String username = (new BufferedReader(new InputStreamReader(
                        System.in))).readLine();
                nc.setName(username);
            } else if(cb instanceof PasswordCallback){
                PasswordCallback pc = (PasswordCallback) cb;
                log.info(pc.getPrompt());
                //采集用户密码
                String password = (new BufferedReader(new InputStreamReader(
                        System.in))).readLine();
                pc.setPassword(password.toCharArray());
            }
        }
    }
   
}
一旦用户收集到用户账号后NameCallback,PasswordCallback对象都会存储他们,与此同时,上述login()方法会基于账号信构建UsernamePasswordPrincipal对象,并保留在登录模块中,而且login()会返回true,当login方法顺利完成用户凭证信息的收集工作后,commit会被触发,她将UsernamePasswordPrincipal对象摆到Subject对象中。
当login方法未能顺利完成用户凭证信息的收集工作后,abort会被触发,将principal等信息破换掉。当登录用户完满的完成自身的业务操作后便可以考虑退出当前的应用,调用logout方法。下面是Principal对象:
package sample;

import java.security.Principal;

/**
*
* @author worldheart
*
*/
//Acegi中的Authentication接口继承了Principal接口
public class UsernamePasswordPrincipal implements Principal {
   
    private String username;
    private String password;

    //存储用户名、密码,比如marissa/koala
    public UsernamePasswordPrincipal(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public String getName() {
        return this.username;
    }

    public String toString() {
        return this.username + "->" + this.password;
    }
   
}

为了使用上述登录模块,需要准备一个jaas配置文件:
Loginmodel.conf放在src下面
ScreenContent {
      sample.ScreenContentLoginModule required;
};
客户应用:
package sample;

import java.io.File;
import java.security.PrivilegedAction;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
*
* @author worldheart
*
*/
public class JaasSecurityClient {

    protected static final Log log = LogFactory
            .getLog(JaasSecurityClient.class);

    public static void main(String argv[]) throws LoginException,
            SecurityException {
        LoginContext ctx = null;
        ctx = new LoginContext("ScreenContent", new UsernamePasswordCallbackHandler());
       
        //marissa用户登录到当前应用中
        ctx.login();
       
        log.info("当前用户已经通过用户认证");

        Subject subject = ctx.getSubject();
        log.info(subject);
       
//        log.info("启用JAAS用户授权能力");
//        log.info("临时目录为," + Subject.doAsPrivileged(subject, new PrivilegedAction() {
//            public Object run() {
//                log.info("当前用户正在经过JAAS授权操作的考验,并正调用目标业务操作");               
//                new File("D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf").exists();
//                return System.getProperty("java.io.tmpdir");
//            }
//        }, null));
        // 退出当前已登录marissa用户
        ctx.logout();
    }

}
在运行客户应用之前还需要提供JVM参数,即引用到loginmoudel.conf配置文件:
-Djava.security.auth.login.config=src/loginmoudel.conf
或者通过javahome/jre/lib/security目录中的java.security配置文件指定上述loginmoudel.conf配置文件:
#login.config.url.l=file:${user.home}/.java.login.config
login.config.url.l=file:d:/eclipse/src/loginmoudel.conf


SecurityContextLoginModule是Acegi内置的一个LoginModel实现,当开发Jaas应用时,用户凭证信息的获取可能来自Acegi,此时,我们便可以采用内置的SecurityContextLoginModel。要使用SecurityContextLoginModule,我们需要在Jaas配置文件中配置它:
ACEGI {
    org.acegisecurity.providers.jaas.SecurityContextLoginModule
        required ignoreMissingAuthentication=true;
};
客户端应用:
package sample;

import java.io.File;
import java.security.PrivilegedAction;

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;

import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* @author worldheart
*
*/
public class AcegiSecurityClient {

    protected static final Log log = LogFactory
            .getLog(AcegiSecurityClient.class);

    public static void main(String argv[]) throws LoginException, SecurityException {
        LoginContext ctx = null;
        //在实际企业应用中,Authentication对象的构建形式多种多样
        SecurityContextHolder.getContext().setAuthentication(
                new UsernamePasswordAuthenticationToken("marissa", "koala"));
        ctx = new LoginContext("ACEGI");
        // marissa用户登录到当前应用中
        ctx.login();
        log.info("当前用户已经通过用户认证");

        Subject subject = ctx.getSubject();
        log.info(subject);
//        log.info("启用JAAS用户授权能力");
//        log.info("临时目录为,"
//                + Subject.doAsPrivileged(subject, new PrivilegedAction() {
//                    public Object run() {
//                        log.info("当前用户正在经过JAAS授权操作的考验,并正调用目标业务操作");
//                        new File(
//                                "D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf")
//                                .exists();
//                        return System.getProperty("java.io.tmpdir");
//                    }
//                }, null));

        // 退出当前已登录marissa用户
        ctx.logout();
       
        //清除已注册的SecurityContext
        SecurityContextHolder.clearContext();
    }

}
注意到我们并未为LoginContext提供CallbackHandler对象,由于Acegi负责提供兼容于Principal的Authentication对象,因此用户凭证的收集也不用CallbackHandler操心了。
在运行客户应用之前还需要提供JVM参数,即引用到loginmoudel.conf配置文件:
-Djava.security.auth.login.config=src/loginmoudel.conf
或者通过javahome/jre/lib/security目录中的java.security配置文件指定上述loginmoudel.conf配置文件:
#login.config.url.l=file:${user.home}/.java.login.config
login.config.url.l=file:d:/eclipse/src/loginmoudel.conf

启用Java安全管理器:大部分java开发者都知道,借助如下JVM参数能够启用java安全管理器,-Djava.security.manager。既然如此,我们通过如下JVM参数运行JaasSecurityClient客户端和AcegiSecurityClient客户端:
-Djava.security.manager -Djava.security.auth.login.config=src/loginmodule.conf
但是这样会出错:java.security.auth.login.config.AccessControlException:access denied
出错原因:默认时,直接借助“-Djava.security.manager”启动java安全管理器,JVM会采用javahome/jre/lib/security中的java.policy策略文件,而这一策略文件并未对上述涉及到的各种权限(比如:createLoginContext.ScreenContent,读取acegi.security.strategyJava属性)进行授权因此抛出了异常。
   为此我们可以提供新的授权信息jaassecuritypolicy.txt策略文件。由于我们需要同LoginContext进行各类操作因此需要提供相关AuthPermission权限给Acegi
SecurityClient,同时我们使用了Commons-Logging,Log4j管理日志,因此还必须将相应的操作权限给这一客户,在操作日志的过程中,客户应用需要操控的:d:/ddlog.log日志文件因此需要将读写权限授给这一客户应用。
grant codebase "file:./-"{
  permission java.io.FilePermission "D:/contactsforchapter8.log", "read, write";
  permission javax.security.auth.AuthPermission "createLoginContext";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
};

grant codeBase
    "file:D:/eclipse/workspace/contactsforchapter8/context/WEB-INF/lib/log4j-1.2.14.jar" {
  permission java.security.AllPermission;
};

grant codeBase
    "file:D:/eclipse/workspace/contactsforchapter8/context/WEB-INF/lib/commons-logging-1.0.4.jar" {
  permission java.security.AllPermission;
};
实际上java的策略文件编写可以通过policytool工具。
运行JaasSecurityClient客户端应用:
-Djava.security.manager -Djava.security.policy=src/jaassecuriypolicy.txt
-Djava.security.auth.login.config=src/loginmodule.conf

类似的运行AcegiSecurityClient的策略文件:
grant codebase "file:./-"{
  permission java.util.PropertyPermission "acegi.security.strategy", "read";
  permission java.io.FilePermission "D:/contactsforchapter8.log", "read, write";
  permission javax.security.auth.AuthPermission "createLoginContext";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
};

grant codeBase
    "file:D:/eclipse/workspace/contactsforchapter8/context/WEB-INF/lib/log4j-1.2.14.jar" {
  permission java.security.AllPermission;
};

grant codeBase
    "file:D:/eclipse/workspace/contactsforchapter8/context/WEB-INF/lib/commons-logging-1.0.4.jar" {
  permission java.security.AllPermission;
};
运行AcegiSecurityClient客户端应用:
-Djava.security.manager -Djava.security.policy=src/acegisecuriypolicy.txt
-Djava.security.auth.login.config=src/loginmodule.conf


启用Jaas的用户授权功能:jaas的授权能力依赖java策略文件,下面提供了另一个版本的jaasSecurityClient客户应用,新增了两行java代码:
LoginContext ctx = null;
        ctx = new LoginContext("ScreenContent", new UsernamePasswordCallbackHandler());
       
        //marissa用户登录到当前应用中
        ctx.login();
       
        log.info("当前用户已经通过用户认证");

        Subject subject = ctx.getSubject();
        log.info(subject);
new File("D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf").exists();
System.getProperty("java.io.tmpdir");
     // 退出当前已登录marissa用户
        ctx.logout();

此时开发者必须往jaassecuritypolicy.txt策略文件中添加如下权限到其中:
permission java.io.FilePermission "D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf", "read";
   permission java.util.PropertyPermission "java.io.tmpdir", "READ";

如果客户要求只具有marissa用户才有权利运行上述两行代码,那么应该这样:
LoginContext ctx = null;
        ctx = new LoginContext("ScreenContent", new UsernamePasswordCallbackHandler());
       
        //marissa用户登录到当前应用中
        ctx.login();
       
        log.info("当前用户已经通过用户认证");

        Subject subject = ctx.getSubject();
        log.info(subject);
       
//        log.info("启用JAAS用户授权能力");
//        log.info("临时目录为," + Subject.doAsPrivileged(subject, new PrivilegedAction() {
//            public Object run() {
//                log.info("当前用户正在经过JAAS授权操作的考验,并正调用目标业务操作");               
//                new File("D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf").exists();
//                return System.getProperty("java.io.tmpdir");
//            }
//        }, null));
        // 退出当前已登录marissa用户
        ctx.logout();
那么jaassecuritypolicy.txt策略文件应该添加如下内容:
grant codebase "file:./-",
    Principal sample.UsernamePasswordPrincipal "marissa" {
   permission java.io.FilePermission "D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf", "read";
   permission java.util.PropertyPermission "java.io.tmpdir", "READ";
};
启动jaassecurityclient客户端:
-Djava.security.manager -Djava.security.policy=src/jaassecuriypolicy.txt
-Djava.security.auth.login.config=src/loginmodule.conf

那么对于acegisecurityclient客户应用,acegisecuritypolicy.txt应该增加:
grant codebase "file:./-",
    Principal org.acegisecurity.providers.UsernamePasswordAuthenticationToken "marissa" {
   permission java.io.FilePermission "D:/eclipse/workspace/contactsforchapter8/src/loginmodule.conf", "read";
  permission java.util.PropertyPermission "java.io.tmpdir", "read";
};
启动:
-Djava.security.manager -Djava.security.policy=src/acegisecuriypolicy.txt
-Djava.security.auth.login.config=src/loginmodule.conf

                                                                          
        直击JaasAuthenticationProvider
配置:
<bean id="jaasAuthenticationProvider" class="org.acegisecurity.providers.jaas.JaasAuthenticationProvider">
   <property name="authorityGranters"
      <bean class="sample.TestAuthorityGranter"/>      
   </property>                                                           
   <property name="callbackHandlers"
      <list>
         <bean class="org.acegisecurity.providers.jaas.JaasNameCallbackHandler"/>
         <bean class="org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/>
   </property>
   <property name="loginConfig" value="classpath:acegi.conf"/>
   <property name="liginContextName" value="ACEGI"/>
</bean>
另外需要将JaasAuthenticationProvider添加到认证管理器:
acegi.conf的内容:
ACEGI {
    sample.TestLoginModule required;
};
注释:authorityGranters属性能够为已经认证用户提供角色映射信息,由于这里的Jaas仅负责用户认证,而授权仍然被acegi接管。TestAuthorityGranter实现类:
package sample;

import java.security.Principal;
import java.util.HashSet;
import java.util.Set;

import org.acegisecurity.providers.jaas.AuthorityGranter;

/**
*
* @author worldheart
*
*/
public class TestAuthorityGranter implements AuthorityGranter {

    public Set grant(Principal principal) {
        Set<String> rtnSet = new HashSet<String>();

        if (principal.getName().equals("TEST_PRINCIPAL")) {
            rtnSet.add("ROLE_USER");
            rtnSet.add("ROLE_ADMIN");
        }

        return rtnSet;
    }

}
下面是TestLoginModel类:
package sample;

import java.security.Principal;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

/**
*
* @author worldheart
*
*/
public class TestLoginModule implements LoginModule {

    private String user;
    private String password;
    private Subject subject;

    public boolean abort() throws LoginException {
        return true;
    }

    public boolean commit() throws LoginException {
        return true;
    }

    public void initialize(Subject subject, CallbackHandler callbackHandler,
            Map sharedState, Map options) {
        this.subject = subject;

        try {
            NameCallback nameCallback = new NameCallback("prompt");
            PasswordCallback passwordCallback = new PasswordCallback("prompt",
                    false);

            callbackHandler.handle(new Callback[] {nameCallback, passwordCallback });

            user = nameCallback.getName();
            password = new String(passwordCallback.getPassword());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean login() throws LoginException {
        if (!user.equals("marissa")) {
            throw new LoginException("用户名不对");
        }

        if (!password.equals("koala")) {
            throw new LoginException("密码不对");
        }

        subject.getPrincipals().add(new Principal() {
            public String getName() {
                return "TEST_PRINCIPAL";
            }
        });

        subject.getPrincipals().add(new Principal() {
            public String getName() {
                return "NULL_PRINCIPAL";
            }
        });

        return true;
    }

    public boolean logout() throws LoginException {
        return true;
    }

}
分享到:
评论

相关推荐

    Tomcat 7-9转载资源

    - **Realm配置**:用于用户认证和授权,例如基于文件的用户数据库、JAAS集成等。 - **JNDI资源**:提供对数据库连接池、邮件服务等外部资源的访问。 通过深入研究这些版本的Tomcat,开发者不仅可以掌握服务器的基本...

    j2ee在线购物网实例源码

    【描述】"j2ee在线购物网实例源码,转载供大家共同学习"表明这是一个共享的学习资源,旨在促进开发者之间的知识交流和技能提升。通过分析和研究这个源码,开发者可以深入理解如何在实际项目中运用J2EE技术栈,包括...

    松下AFPX-C38AT PLC控制双切刀三边封制袋机系统的伺服电机与温控程序解析

    内容概要:本文详细介绍了基于松下AFPX-C38AT PLC平台的双切刀三边封制袋机控制系统。该系统通过PLC控制四台伺服电机进行切刀和移刀动作以及二轴送袋定位,同时管理两台变频器实现主机和放料电机的同步调速,并利用WK8H模块进行16路温控输出。文中展示了具体的PLC编程实例,如伺服电机的DRVI指令、变频器的同步控制、温控模块的PID调节等。此外,还讨论了硬件配置、触摸屏界面设计、通信协议设置等方面的内容,强调了系统的灵活性和稳定性。 适合人群:从事工业自动化控制领域的工程师和技术人员,尤其是对PLC编程和伺服电机控制感兴趣的读者。 使用场景及目标:适用于需要深入了解PLC控制系统的开发人员,帮助他们掌握伺服电机控制、变频器同步调速和温控模块编程的具体方法,提高实际项目中的应用能力。 其他说明:文章不仅提供了详细的编程示例,还分享了许多实际调试的经验和技巧,有助于读者更好地理解和应用相关技术。

    计算机审计软件的特点与应用.pdf

    计算机审计软件的特点与应用.pdf

    离散傅里叶变换(DFT)分析-Discrete Fourier Transform (DFT) Analysis-matlab

    离散傅里叶变换(DFT)分析 函数[F,FT,Phase]=DFT(T,Signal,Fi,FF,Res,P,Cursor)计算离散傅里叶变换(DFT) 功能概述:离散傅立叶变换(DFT)分析 函数[F,FT,Phase]=DFT(T,Signal,Fi,FF,Res,P,Cursor)是频率域信号分析的通用工具。它在指定的频率范围内计算信号的离散傅立叶变换(DFT),提供可定制的可视化选项。 输入 T(采样时间向量,秒):表示与正在分析的信号样本相对应的时间点。 信号:您希望在频域中检查的数据集或信号。 FI(以赫兹为单位的初始频率):频率分析的起点。 FF(最终频率(Hz):频率分析范围的上限。 Res(分辨率以赫兹为单位):确定傅立叶变换的精度。较小的值会增加分辨率。 P(打印选项): 0:没有生成图。 1: 仅显示震级图。 2: 显示大小和相位图。 光标(在绘图上启用光标)(可选): 1: 当P不

    Matlab实现电转气协同与碳捕集的虚拟电厂优化调度系统

    内容概要:本文详细介绍了如何在Matlab中构建一个综合了垃圾焚烧、碳捕集和电转气(P2G)技术的虚拟电厂优化调度系统。该系统旨在通过合理的设备参数设置、多能流耦合约束以及分段碳价机制的目标函数设计,实现环保与经济效益的最大化。文中展示了具体的数学模型建立方法,如设备参数初始化、能量平衡约束、碳捕集与P2G物料平衡、分时碳成本计算等,并讨论了求解技巧,包括变量定义、求解器选择和约束条件处理等方面的内容。此外,还探讨了垃圾焚烧发电占比变化对P2G设备启停策略的影响,以及不同时间段内的最优调度策略。 适合人群:从事能源系统优化研究的专业人士,特别是那些熟悉Matlab编程并希望深入了解虚拟电厂调度机制的人群。 使用场景及目标:适用于希望提高虚拟电厂运行效率的研究机构或企业。通过本项目的实施,能够更好地理解如何整合多种能源技术,在满足电力供应需求的同时减少碳排放,降低成本。具体应用场景包括但不限于:制定更加科学合理的发电计划;评估新技术引入后的潜在效益;探索不同政策环境下的最佳运营模式。 其他说明:文中提到的一些关键技术点,如碳捕集与P2G的协同工作、垃圾焚烧发电的灵活应用等,对于推动清洁能源的发展具有重要意义。同时,作者也在实践中遇到了一些挑战,如约束条件之间的冲突等问题,并分享了解决这些问题的经验。

    栈的入栈和出栈.pdf

    入栈和出栈的基本操作

    V型永磁同步电机永磁体参数调整与优化技术解析及Maxwell仿真应用

    内容概要:本文详细探讨了V型永磁同步电机中永磁体参数调整的方法和技术,特别是在Maxwell软件中的应用。首先介绍了V型永磁体的关键参数(如V型夹角、磁钢厚度、极弧系数等)及其对电机性能的影响。接着讨论了利用Maxwell进行参数化建模、参数扫描、优化方法(如响应面法、多目标遗传算法)的具体步骤和注意事项。文中还提供了多个实用脚本,涵盖从几何建模、材料属性设置到求解器配置、后处理分析等多个方面。此外,强调了优化过程中应注意的问题,如退磁校验、磁密饱和、涡流损耗等,并给出了一些实战技巧。 适合人群:从事电机设计与仿真的工程师、研究人员,尤其是熟悉Maxwell软件的用户。 使用场景及目标:帮助用户掌握V型永磁同步电机永磁体参数调整的技术要点,提高电机性能指标(如降低齿槽转矩、减少谐波失真、优化转矩波动等)。通过实例和脚本指导,使用户能够在Maxwell中高效地完成仿真和优化任务。 其他说明:文章不仅提供了详细的理论解释,还包括大量实践经验分享和常见问题解决方案,有助于读者更好地理解和应用相关技术。

    光伏发电系统仿真:基于扰动观察法的最大功率点跟踪与储能控制策略

    内容概要:本文详细介绍了光伏发电系统的仿真建模及其控制策略。主要内容分为四个部分:首先是光伏发电系统仿真模型的搭建,通过数学公式和Python代码实现了太阳电池特性的模拟;其次,探讨了扰动观察法(PO)作为最大功率点跟踪(MPPT)的方法,展示了其实现逻辑和代码示例;第三部分讨论了带储能控制策略的设计,利用状态机管理储能系统的充放电过程,确保电力供应平稳;最后进行了负载突变验证实验,评估了系统在极端条件下的稳定性和可靠性。通过这些步骤,作者不仅解释了理论背景,还提供了具体的实现细节和技术挑战。 适合人群:对光伏发电系统感兴趣的研究人员、工程师以及相关领域的学生。 使用场景及目标:适用于希望深入了解光伏发电系统工作原理的人群,尤其是关注最大功率点跟踪技术和储能控制系统设计的应用开发者。目标是帮助读者掌握光伏系统仿真的关键技术,为实际项目提供理论支持和技术指导。 其他说明:文中提供的代码片段可以直接用于实验环境,便于读者动手实践。此外,针对可能出现的问题如耦合振荡等,给出了相应的解决方案。

    电机设计中8极48槽辐条型转子桥参数化建模与优化(基于Maxwell)

    内容概要:本文详细介绍了8极48槽辐条型电机转子桥的参数化建模方法及其优化过程。通过将桥的厚度、过渡圆弧半径和倒角角度作为变量进行参数化处理,利用Maxwell软件实现了自动化仿真和优化。文中展示了具体的Python和VBScript代码示例,用于动态调整桥部尺寸并监控磁密分布,最终通过参数扫描找到最佳设计参数组合,显著降低了磁密峰值和扭矩波动,提高了电机的整体性能。 适合人群:从事电机设计与仿真的工程师和技术人员,尤其是熟悉Maxwell软件的用户。 使用场景及目标:适用于需要优化电机转子桥结构的设计项目,旨在提高电机性能,降低磁密峰值和扭矩波动,确保机械强度的同时提升电磁性能。 其他说明:文章提供了详细的代码示例和操作步骤,帮助读者快速掌握参数化建模技巧,并强调了网格设置和多参数联动优化的重要性。

    风电调频并网系统中高效仿真的4机2区模型及其PSS模式应用

    内容概要:本文详细介绍了用于风电调频并网系统的4机2区模型,该模型能够在短时间内完成长时间跨度的仿真,极大提高了科研和工程分析的效率。文中具体阐述了模型的结构特点,包括两个区域内的发电机组分布、连接方式以及风电场的虚拟惯量控制机制。此外,文章深入解析了四种PSS(电力系统稳定器)模式的工作原理及其在不同工况下的表现,特别是针对风电接入带来的低频振荡问题进行了讨论。通过实例展示了PSS模式对系统稳定性的显著提升效果,并分享了一些实用的调参技巧。 适合人群:从事电力系统仿真、风电并网研究的专业技术人员及高校相关专业师生。 使用场景及目标:适用于需要进行大规模风电调频并网系统仿真的场合,旨在帮助研究人员更好地理解和解决风电接入对电网稳定性的影响,优化风电并网友好度。 其他说明:文章不仅提供了理论分析,还包括具体的Python和Matlab代码示例,便于读者理解和实践。同时强调了在高风电渗透率条件下选择合适PSS模式的重要性。

    LabVIEW Excel工具包:高效自动化生成带格式测试报告的方法与技巧

    内容概要:本文详细介绍了如何使用LabVIEW的Excel工具包来高效生成带有特定格式的测试报告。首先,准备一个Excel模板文件,设置好表头样式、公司LOGO和合并单元格,并用特殊标记占位。然后,通过LabVIEW代码进行Excel操作,如初始化Excel应用、打开和复制模板文件、写入测试数据、设置条件格式、调整列宽以及保存和关闭文件。文中强调了使用二维数组批量写入数据、条件格式设置超标数据标红、精确控制列宽、避免文件覆盖等问题。此外,还提到了一些常见问题及其解决方案,如Excel进程卡死、数据错位等。最终,通过这些方法可以将原本复杂的报告生成过程大幅简化,提高工作效率。 适合人群:熟悉LabVIEW编程的工程师和技术人员,尤其是从事自动化测试和数据分析工作的人员。 使用场景及目标:适用于需要频繁生成格式一致的测试报告的场景,如汽车电子测试、环境监测等领域。目标是通过LabVIEW的Excel工具包实现自动化、高效的报告生成,节省时间和精力。 阅读建议:读者可以通过本文学习如何利用LabVIEW的Excel工具包快速生成带格式的测试报告,掌握关键技术和最佳实践,从而提升工作效率。同时,在实践中应注意模板的设计和代码的优化,以应对各种复杂的需求变化。

    main (4).ipynb

    main (4).ipynb

    计算机数学基础(下).pdf

    计算机数学基础(下).pdf

    基于MATLAB的多智能体系统一致性算法在电力系统分布式经济调度中的应用

    内容概要:本文详细介绍了如何利用MATLAB实现基于多智能体系统一致性算法的电力系统分布式经济调度策略。首先,通过构建邻接矩阵生成函数,处理电网拓扑结构,确保每个节点能够正确获取邻居信息。接着,定义发电机成本函数和负荷效用函数,将两者统一为二次函数形式,以便更好地兼顾发电侧和用电侧的经济性。然后,重点展示了核心的一致性迭代算法,通过拉普拉斯矩阵实现信息扩散,使发电机和负荷之间的增量成本和效益逐步趋于一致。此外,文中还提供了具体的测试案例,包括10台发电机和19个柔性负荷组成的系统,展示了算法的高效性和鲁棒性。最后,强调了通信拓扑设计对收敛速度的影响,并分享了一些调试经验和潜在的应用前景。 适合人群:电力系统研究人员、自动化控制工程师、MATLAB开发者以及对分布式优化算法感兴趣的学者。 使用场景及目标:适用于电力系统经济调度的研究与开发,旨在提高调度效率、降低成本的同时保障系统的稳定性。通过分布式算法替代传统的集中式调度方式,增强系统的隐私保护能力和计算效率。 其他说明:文中提供的MATLAB代码不仅可用于学术研究,还可以进一步应用于实际工程项目中,特别是在含有大量新能源接入的现代电力系统中,展现出更大的优势。

    计算机数控装置课件.pdf

    计算机数控装置课件.pdf

    机器人路径规划中RRT算法的优化与改进方案

    内容概要:本文详细介绍了RRT(快速扩展随机树)路径规划算法的多个优化方法及其具体实现。首先指出原始RRT存在的缺陷,如路径质量差、计算时间长等问题。然后提出了一系列改进措施,包括目标偏向采样、自适应步长控制、路径平滑处理以及椭圆约束采样等。每个改进都附有具体的Python代码片段,并解释了其实现思路和技术细节。此外,文中还讨论了不同改进方案之间的协同使用效果,强调了实际应用中的注意事项。 适合人群:从事机器人路径规划研究的技术人员,尤其是有一定编程基础并希望深入了解RRT算法优化的人群。 使用场景及目标:适用于各种需要高效路径规划的应用场合,如仓储机器人、无人机避障、机械臂运动规划等。主要目标是提高路径规划的速度和质量,同时减少计算资源消耗。 其他说明:尽管这些改进显著提升了RRT的表现,但在实际部署时仍需考虑传感器噪声和系统延迟等因素的影响。作者分享了许多个人实践经验,为读者提供了宝贵的参考。

    计算机试题实例分析.pdf

    计算机试题实例分析.pdf

    基于PLC的自动门禁系统设计与实现:三菱FX3U系列的应用实例

    内容概要:本文详细介绍了利用三菱FX3U系列PLC构建自动门禁系统的全过程。首先阐述了硬件配置方案,包括选用三菱FX3U-32MT作为主控制器,配备多种传感器如红外对射、地磁以及防夹传感器等,并采用适当的执行机构进行门的开闭控制。接着深入解析了梯形图逻辑的设计,涵盖基本开闭逻辑、安全回路设计、滤波处理等方面的内容。文中特别强调了几个关键技术点,如通过定时器控制门的开启时间和防夹保护措施,解决了红外传感器误触发的问题,并引入了GX Works2模拟器用于程序调试。此外,还讨论了如何通过RS485通信接口实现身份验证模块的联网功能及其故障转移机制。最后,作者分享了一些实用的经验教训,例如避免信号干扰的方法和确保系统稳定性的冗余设计。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是对PLC编程有一定基础的人群。 使用场景及目标:适用于需要构建高效可靠的自动门禁系统的场合,旨在提高门禁系统的安全性、可靠性和智能化水平。 其他说明:文中提到的具体案例和解决方案可以为类似项目的实施提供宝贵的参考价值。同时,作者还提供了许多调试技巧和注意事项,有助于读者更好地理解和应用所学知识。

    基于S7-200 PLC与组态王的全自动洗衣机控制系统设计及应用

    内容概要:本文详细介绍了基于西门子S7-200 PLC和组态王软件构建的全自动洗衣机控制系统。主要内容涵盖IO分配、梯形图程序设计、接线图原理图绘制以及组态画面的设计。通过合理的IO分配,如启动按钮、水位传感器等输入设备和电机、进水阀等输出设备的定义,确保系统的精确控制。梯形图程序实现了洗衣机的基本功能,如启动自锁、进水、水位检测、电机启动和排水等功能。接线图确保了电气连接的安全性和可靠性,而组态画面提供了直观的操作界面,使用户能够轻松监控和操作洗衣机。此外,文中还讨论了一些常见问题及其解决方案,如排水阀卡滞、变频器控制等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC编程和组态软件有一定了解的从业者。 使用场景及目标:适用于需要设计和实施全自动洗衣机控制系统的工业生产和家庭应用场景。目标是提高洗衣机的自动化程度,增强用户体验,确保系统的稳定性和安全性。 其他说明:本文不仅提供了详细的理论讲解,还包括了许多实用的技术细节和调试经验,有助于读者更好地理解和掌握相关技术和方法。

Global site tag (gtag.js) - Google Analytics