- 浏览: 518088 次
- 性别:
- 来自: 惠州
-
文章分类
- 全部博客 (255)
- ant (1)
- springMVC (2)
- ajax (4)
- oracle (12)
- SSH (13)
- struts1 (2)
- Hibernate (14)
- spring (5)
- jstl (1)
- 连接池 (1)
- acegi (4)
- java (17)
- jquery (11)
- div+css (4)
- drupal (1)
- php (8)
- freemaker调模板生成静态页面 (1)
- xml (1)
- json (2)
- javascript (9)
- 正则表达式 (4)
- Ext (8)
- jdbc (1)
- sql server (2)
- perl (5)
- db4o (1)
- webservice (4)
- flex (13)
- it资讯 (1)
- joomla (0)
- 设计模式 (1)
- struts2 (4)
- s2sh (8)
- linux (3)
- ejb (2)
- android旅途 (24)
- android (36)
- C/C++ (16)
- mysql (1)
最新评论
-
fengyuxing168:
IBelyService bs = IBelyService. ...
为 Android 添加 Java 层服务也就是添加自定义的aidl服务到serviceManager 通过ServiceManager.getService取 -
dengzhangtao:
"由于ActivityManagerService是 ...
binder理解 -
yzyspy:
ActivityManagerService:startHom ...
Android的Launcher成为系统中第一个启动的,也是唯一的 -
Matchstick:
使用SELECT DISTINCT alias FROM Po ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题 -
dlheart:
没看懂你什么意思啊,我遇到的问题是一对多,设了fetch = ...
hibernate 一对多表查询时fetchMode.join 生成left outer join 出来数据重复问题
Spring+Hibernate+Acegi 的初次体验
一 :高层设计 核心组件
大多数的企业级应用有四种基本的安全需求。
1 :需要对主体进行鉴别
2 :需要对web请求进行保护
3 :需要对服务层方法进行保护
4 :很多情况下需要对域对象实例进行保护
Acegi系统提供了一个通用的框架,它可以满足所有这四种企业安全级的需求。
到现在我也没有弄明白Acegi里面很多的功能,刚刚开始学的时候我就已经被它那繁琐的配置震慑住了,不过当我动起手来一步步实现的时候,才发现其实它远没有那么难,当然随着学习的深入,会渐渐再发现这一点吧,现在就让我们初学者一切体验Acegi的功能吧!
以我传统的例子为例:
毕业设计选题系统,三种角色:
教师
学生
管理员
我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的
admin.jsp
stu.jsp
teacher.jsp
在数据库中的表结构如下(很多属性略):
id
user
password
type
about
type是用来存储用户的类别,分别有a,t,s分别对应三种角色 ,
about对应的是acegi里所需要的enable,用户是否可用
在model里,我们采用了继承关系:
父类user:
package subject.model;
public abstract class User extends BaseObject {
private Integer id;
private String user;
private String password;
private String name;
private String telphone;
// set and get method
public abstract String getType(); // 这个是用来反映用户角色的关键函数,在子类实现,从而实现多态
}
子类的实现(Teacher):
package subject.model;
import subject.Constants;
public class Teacher extends User {
private String level; // 教师的职称
// set and get method
public String getType() {
return Constants.TEACHER;
}
}
子类的实现(Student):
package subject.model;
import subject.Constants;
public class Student extends User {
private static final long serialVersionUID = 1L;
private SchoolClass schoolClass; // 学生的班级
private String sn; // 学生的学号
// set and get method
public String getType() {
return Constants.STUDENT;
}
}
子类的实现(Admin):
package subject.model;
import subject.Constants;
public class Admin extends User {
private String grade; // 管理员的级别
// set and get method
public String getType() {
return Constants.ADMIN;
}
}
对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,
学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!
这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:
< hibernate - mapping >
< class name = " subject.model.User " discriminator - value = " not null " >
< id name = " id " >
< generator class = " increment " />
</ id >
< discriminator column = " type " type = " character " />
< property name = " user " />
< property name = " password " />
< property name = " name " />
< property name = " telphone " />
< subclass name = " subject.model.Admin " discriminator - value = " a " >
< property name = " grade " column = " sn " />
</ subclass >
< subclass name = " subject.model.Teacher " discriminator - value = " t " >
< property name = " level " column = " sn " />
</ subclass >
< subclass name = " subject.model.Student " discriminator - value = " s " >
< property name = " sn " />
< many - to - one name = " schoolClass " class = " subject.model.SchoolClass "
column = " about " update = " false " insert = " false " />
</ subclass >
</ class >
</ hibernate - mapping >
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆
在Spring中Hibernate的配置只介绍不说明:
<!-- 定义DBCP数据源 -->
< bean id = " dataSource " class = " org.apache.commons.dbcp.BasicDataSource " destroy - method = " close " >
< property name = " driverClassName " value = " com.mysql.jdbc.Driver " />
< property name = " url " value = " jdbc:mysql://localhost/subject?useUnicode=true&characterEncoding=gbk " />
< property name = " username " value = " root " />
< property name = " password " value = "" />
< property name = " maxActive " value = " 100 " />
< property name = " maxIdle " value = " 30 " />
< property name = " maxWait " value = " 1000 " />
< property name = " defaultAutoCommit " value = " true " />
< property name = " removeAbandoned " value = " true " />
< property name = " removeAbandonedTimeout " value = " 60 " />
</ bean >
<!-- Hibernate -->
< bean id = " sessionFactory " class = " org.springframework.orm.hibernate3.LocalSessionFactoryBean " >
< property name = " dataSource " ref = " dataSource " />
< property name = " mappingResources " >
< list >
< value > subject / model / User.hbm.xml </ value >
</ list >
</ property >
< property name = " hibernateProperties " >
< props >
< prop key = " hibernate.dialect " > org.hibernate.dialect.MySQLInnoDBDialect </ prop >
</ props >
</ property >
</ bean >
< bean id = " transactionManager " class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
< property name = " sessionFactory " ref = " sessionFactory " />
</ bean >
<!-- Dao对象 -->
< bean id = " userDao " class = " subject.dao.hibernate.UserDaoImpl " >
< property name = " sessionFactory " ref = " sessionFactory " />
</ bean >
<!-- 业务逻辑 -->
< bean id = " txProxyTemplate " abstract = " true " class = " org.springframework.transaction.interceptor.TransactionProxyFactoryBean " >
< property name = " transactionManager " ref = " transactionManager " />
< property name = " transactionAttributes " >
< props >
< prop key = " save* " > PROPAGATION_REQUIRED </ prop >
< prop key = " remove* " > PROPAGATION_REQUIRED </ prop >
< prop key = " get* " > PROPAGATION_REQUIRED,readOnly </ prop >
</ props >
</ property >
</ bean >
< bean id = " userManager " parent = " txProxyTemplate " >
< property name = " target " >
< bean class = " subject.service.impl.UserManagerImpl " >
< property name = " userDao " ref = " userDao " />
</ bean >
</ property >
</ bean >
<!-- Struts -->
< bean name = " /user " class = " subject.web.action.UserAction " singleton = " false " >
< property name = " userManager " >
< ref bean = " userManager " />
</ property >
</ bean >
上面具体的不用了解,无非就是调用和数据库的操作,下面就要对Acegi进行声明了:我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆,我们想主要在这样的系统中需要的安全策略都有哪些?
1 .用户的登陆
2 .防止多个用户登陆一个帐号
3 .用户的注销
4 .防止非法用户的访问
我这个程序所涉及到的只有这些,下面就进行说明:
在web.xml的声明:
<!-- Acegi安全控制 Filter 配置 -->
< filter >
< filter - name > securityFilter </ filter - name >
< filter - class > org.acegisecurity.util.FilterToBeanProxy </ filter - class >
< init - param >
< param - name > targetClass </ param - name >
< param - value > org.acegisecurity.util.FilterChainProxy </ param - value >
</ init - param >
</ filter >
< filter - mapping >
< filter - name > securityFilter </ filter - name >
< url - pattern > /**/ /* </url-pattern>
</filter-mapping>
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这样就简化了web.xml的配置,并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。
<!-- ======================== FILTER CHAIN ======================= -->
< bean id = " filterChainProxy " class = " org.acegisecurity.util.FilterChainProxy " >
< property name = " filterInvocationDefinitionSource " >
< value >
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**/ /* *=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,
securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
大体上先介绍一下:
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
logoutFilter:用户的注销
authenticationProcessingFilter:处理登陆请求
exceptionTranslationFilter:异常转换过滤器
filterInvocationInterceptor:在访问前进行权限检查
这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。
下面就是对这些过滤器的具体声明:
只对有用的地方进行声明,别的地方几乎都是默许的
<!-- ======================== FILTER ======================= -->
< bean id = " httpSessionContextIntegrationFilter " class = " org.acegisecurity.context.HttpSessionContextIntegrationFilter " />
< bean id = " logoutFilter " class = " org.acegisecurity.ui.logout.LogoutFilter " >
< constructor - arg value = " /index.htm " /> // 离开后所转向的位置
< constructor - arg >
< list >
< bean class = " org.acegisecurity.ui.logout.SecurityContextLogoutHandler " />
</ list >
</ constructor - arg >
< property name = " filterProcessesUrl " value = " /logout.htm " /> // 定义用户注销的地址,
</ bean >
下面的这个过滤器处理登陆请求,我们根据自己的需求有了自己的实现:
< bean id = " authenticationProcessingFilter " class = " subject.web.filter.UserAuthenticationProcessingFilter " >
< property name = " authenticationManager " ref = " authenticationManager " />
< property name = " authenticationFailureUrl " value = " /login.htm?error=wrong " /> // 登陆失败的地址
< property name = " defaultTargetUrl " value = " /login.htm " /> // 登陆成功的地址
< property name = " filterProcessesUrl " value = " /j_security_check " /> // 登陆请求的地址
< property name = " userManager " ref = " userManager " /> // 自己添加的属性,这样就可以访问到我们的业务逻辑
< property name = " exceptionMappings " > // 出现异常所对应的地址
< value >
org.acegisecurity.AuthenticationException =/ login.htm ? error = fail 登陆失败
org.acegisecurity.concurrent.ConcurrentLoginException =/ login.htm ? error = too 已登陆了
</ value >
</ property >
</ bean >
作用未知 :
< bean id = " securityContextHolderAwareRequestFilter " class = " org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter " />
异常转换过滤器
< bean id = " exceptionTranslationFilter " class = " org.acegisecurity.ui.ExceptionTranslationFilter " >
< property name = " authenticationEntryPoint " >
< bean class = " org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint " > //进行表单认证;
<property name = " loginFormUrl " value = " /login.htm?error=please " /> // 如果用户没登陆就想访问,先到这里登陆吧
<property name = " forceHttps " value = " false " />
</bean >
</property >
</bean >
在访问前进行权限检查
< bean id = " filterInvocationInterceptor " class = " org.acegisecurity.intercept.web.FilterSecurityInterceptor " >
< property name = " authenticationManager " ref = " authenticationManager " /> 认证服务
< property name = " accessDecisionManager " >
< bean class = " org.acegisecurity.vote.AffirmativeBased " >
< property name = " allowIfAllAbstainDecisions " value = " false " />
< property name = " decisionVoters " >
< list >
< bean class = " org.acegisecurity.vote.RoleVoter " >
// 这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀?我没加
< property name = " rolePrefix " value = "" />
</ bean >
</ list >
</ property >
</ bean >
</ property >
< property name = " objectDefinitionSource " >
< value >
PATTERN_TYPE_APACHE_ANT
/ admin.htm *= a 这里就是数据库中对应的tyep a
/ student *= s 由于没有前缀和数据库里一样
/ teacher *= t
</ value >
</ property >
</ bean >
记录事件
< bean id = " loggerListener " class = " org.acegisecurity.event.authentication.LoggerListener " />
下面就要说明我们的认证服务了,其起到的关键作用就是用来保证用户登陆身份的验证:
它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
先声明一个管理器吧,在上面的过滤器中都已经用到过了
<!-- ======================== AUTHENTICATION ======================= -->
< bean id = " authenticationManager " class = " org.acegisecurity.providers.ProviderManager " >
< property name = " providers " >
< list >
// 我仅仅用到 从数据库中读取用户信息验证身份
< ref local = " daoAuthenticationProvider " />
</ list >
</ property >
< property name = " sessionController " >
< bean id = " concurrentSessionController "
class = " org.acegisecurity.concurrent.ConcurrentSessionControllerImpl " >
< property name = " maximumSessions " >
< value > 1 </ value > // 每个用户同时登陆一位
</ property >
< property name = " sessionRegistry " >
< bean id = " sessionRegistry " class = " org.acegisecurity.concurrent.SessionRegistryImpl " />
</ property >
< property name = " exceptionIfMaximumExceeded " value = " true " />
</ bean >
</ property >
</ bean >
来实现唯一的一个Provider,从数据库验证身份
< bean id = " daoAuthenticationProvider " class = " org.acegisecurity.providers.dao.DaoAuthenticationProvider " >
< property name = " userDetailsService " >
< bean id = " jdbcDaoImpl "
class = " org.acegisecurity.userdetails.jdbc.JdbcDaoImpl " >
< property name = " dataSource " ref = " dataSource " />
< property name = " usersByUsernameQuery " >
< value >
// 查找用户的查询语句,只需要把你数据库中的用户和密码以及enable相对应上就行
select user,password,about from user where user = ?</ value >
</ property >
< property name = " authoritiesByUsernameQuery " >
< value >
// 这里就是把用户和权限对应上,在appfuse中用的两个表,
// 我都放一个表里了,
// 所以就用这一个就行问题的关键是要让它能找到两个字段,构成一个对象
select user,type from user where user = ?
</ value >
</ property >
</ bean >
</ property >
< property name = " userCache " > // 缓存都这么写:
< bean class = " org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache " >
< property name = " cache " >
< bean class = " org.springframework.cache.ehcache.EhCacheFactoryBean " >
< property name = " cacheManager " >
< bean class = " org.springframework.cache.ehcache.EhCacheManagerFactoryBean " />
</ property >
< property name = " cacheName " value = " userCache " />
</ bean >
</ property >
</ bean >
</ property >
</ bean >
==============
对于上面登陆请求的处理器我借鉴了springSide,实现的方法如下:
package subject.web.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.acegisecurity.userdetails.UserDetails;
import subject.Constants;
import subject.model.User;
import subject.service.UserManager;
public class UserAuthenticationProcessingFilter extends
AuthenticationProcessingFilter
{
private UserManager userManager;
public void setUserManager( UserManager userManager )
{
this .userManager = userManager;
}
protected boolean requiresAuthentication( HttpServletRequest request ,
HttpServletResponse response )
{
boolean requiresAuth = super.requiresAuthentication( request, response );
HttpSession httpSession = null ;
try
{
httpSession = request.getSession( false );
}
catch ( IllegalStateException ignored )
{
}
if ( httpSession != null )
{
if ( httpSession.getAttribute( Constants.USER ) == null )
{
if ( ! requiresAuth )
{
SecurityContext sc = SecurityContextHolder.getContext();
Authentication auth = sc.getAuthentication();
if ( auth != null
&& auth.getPrincipal() instanceof UserDetails )
{
UserDetails ud = (UserDetails) auth.getPrincipal(); // 上面声明的sql无非就是要包装成这个对象
User user = userManager.getUser( ud.getUsername() );从业务逻辑里找到用户,放到session里
httpSession.setAttribute( Constants.USER, user );
}
}
}
}
return requiresAuth;
}
}
在看看我的login.htm在登陆成功时是怎么工作的吧?
public class UserAction extends BaseAction
{
private UserManager mgr;
public void setUserManager( UserManager mgr )
{
this .mgr = mgr;
}
public ActionForward login( ActionMapping mapping , ActionForm form ,
HttpServletRequest request , HttpServletResponse response )
throws Exception
{
User user = (User) getSessionObject( request, Constants.USER );
ActionMessages msg = new ActionMessages();
if ( user != null )
{
return new ActionForward( user.getType() + " .htm " , true );成功就去type.htm
}
else
{
String error = getParameter( request, Constants.ERROR );
if ( error != null )对于不同的错误,都加以提示
{
if ( error.equalsIgnoreCase( " wrong " ) )
msg.add( " msg " , new ActionMessage( " fail.login.wrong " ) );
else if ( error.equalsIgnoreCase( " too " ) )
msg.add( " msg " , new ActionMessage( " fail.login.too " ) );
else if ( error.equalsIgnoreCase( " fail " ) )
msg.add( " msg " , new ActionMessage( " fail.login.fail " ) );
else
msg.add( " msg " , new ActionMessage( " fail.login.please " ) );
}
else
msg.add( " msg " , new ActionMessage( " fail.login.please " ) );
}
saveErrors( request, msg );
return mapping.findForward( " fail " );
}
}
当然,Acegi需要介绍的东西太多了,我只把我这次认为有必要解释的东西写在了上面让大家来参考,作为能google到的东西,比如对于认证的方式还有很多,我就没有详细的介绍,在学习Acegi过程中,把它自带的例子弄清楚很关键,希望大家一起学习一起共勉!
一 :高层设计 核心组件
大多数的企业级应用有四种基本的安全需求。
1 :需要对主体进行鉴别
2 :需要对web请求进行保护
3 :需要对服务层方法进行保护
4 :很多情况下需要对域对象实例进行保护
Acegi系统提供了一个通用的框架,它可以满足所有这四种企业安全级的需求。
到现在我也没有弄明白Acegi里面很多的功能,刚刚开始学的时候我就已经被它那繁琐的配置震慑住了,不过当我动起手来一步步实现的时候,才发现其实它远没有那么难,当然随着学习的深入,会渐渐再发现这一点吧,现在就让我们初学者一切体验Acegi的功能吧!
以我传统的例子为例:
毕业设计选题系统,三种角色:
教师
学生
管理员
我想让他们的登陆都在一个界面下自动识别,而无需进行身份选择,登陆后,他们将分别到各自的
admin.jsp
stu.jsp
teacher.jsp
在数据库中的表结构如下(很多属性略):
id
user
password
type
about
type是用来存储用户的类别,分别有a,t,s分别对应三种角色 ,
about对应的是acegi里所需要的enable,用户是否可用
在model里,我们采用了继承关系:
父类user:
package subject.model;
public abstract class User extends BaseObject {
private Integer id;
private String user;
private String password;
private String name;
private String telphone;
// set and get method
public abstract String getType(); // 这个是用来反映用户角色的关键函数,在子类实现,从而实现多态
}
子类的实现(Teacher):
package subject.model;
import subject.Constants;
public class Teacher extends User {
private String level; // 教师的职称
// set and get method
public String getType() {
return Constants.TEACHER;
}
}
子类的实现(Student):
package subject.model;
import subject.Constants;
public class Student extends User {
private static final long serialVersionUID = 1L;
private SchoolClass schoolClass; // 学生的班级
private String sn; // 学生的学号
// set and get method
public String getType() {
return Constants.STUDENT;
}
}
子类的实现(Admin):
package subject.model;
import subject.Constants;
public class Admin extends User {
private String grade; // 管理员的级别
// set and get method
public String getType() {
return Constants.ADMIN;
}
}
对于三者所共有的属性在数据库里,都存在一个字段,而依据不同的角色拥有不同的含义,
学生的班级则存放在了about里,只要学生有班级,他就able,否则就enable了!而管理员和教师则默认为1!
这种是属于一个继承树存放在一个表的情况,Hibernate的配置如下:
< hibernate - mapping >
< class name = " subject.model.User " discriminator - value = " not null " >
< id name = " id " >
< generator class = " increment " />
</ id >
< discriminator column = " type " type = " character " />
< property name = " user " />
< property name = " password " />
< property name = " name " />
< property name = " telphone " />
< subclass name = " subject.model.Admin " discriminator - value = " a " >
< property name = " grade " column = " sn " />
</ subclass >
< subclass name = " subject.model.Teacher " discriminator - value = " t " >
< property name = " level " column = " sn " />
</ subclass >
< subclass name = " subject.model.Student " discriminator - value = " s " >
< property name = " sn " />
< many - to - one name = " schoolClass " class = " subject.model.SchoolClass "
column = " about " update = " false " insert = " false " />
</ subclass >
</ class >
</ hibernate - mapping >
上面的这些都是模型的基础,下面再讲怎么样配合Spring和Acegi实现系统的安全与登陆
在Spring中Hibernate的配置只介绍不说明:
<!-- 定义DBCP数据源 -->
< bean id = " dataSource " class = " org.apache.commons.dbcp.BasicDataSource " destroy - method = " close " >
< property name = " driverClassName " value = " com.mysql.jdbc.Driver " />
< property name = " url " value = " jdbc:mysql://localhost/subject?useUnicode=true&characterEncoding=gbk " />
< property name = " username " value = " root " />
< property name = " password " value = "" />
< property name = " maxActive " value = " 100 " />
< property name = " maxIdle " value = " 30 " />
< property name = " maxWait " value = " 1000 " />
< property name = " defaultAutoCommit " value = " true " />
< property name = " removeAbandoned " value = " true " />
< property name = " removeAbandonedTimeout " value = " 60 " />
</ bean >
<!-- Hibernate -->
< bean id = " sessionFactory " class = " org.springframework.orm.hibernate3.LocalSessionFactoryBean " >
< property name = " dataSource " ref = " dataSource " />
< property name = " mappingResources " >
< list >
< value > subject / model / User.hbm.xml </ value >
</ list >
</ property >
< property name = " hibernateProperties " >
< props >
< prop key = " hibernate.dialect " > org.hibernate.dialect.MySQLInnoDBDialect </ prop >
</ props >
</ property >
</ bean >
< bean id = " transactionManager " class = " org.springframework.orm.hibernate3.HibernateTransactionManager " >
< property name = " sessionFactory " ref = " sessionFactory " />
</ bean >
<!-- Dao对象 -->
< bean id = " userDao " class = " subject.dao.hibernate.UserDaoImpl " >
< property name = " sessionFactory " ref = " sessionFactory " />
</ bean >
<!-- 业务逻辑 -->
< bean id = " txProxyTemplate " abstract = " true " class = " org.springframework.transaction.interceptor.TransactionProxyFactoryBean " >
< property name = " transactionManager " ref = " transactionManager " />
< property name = " transactionAttributes " >
< props >
< prop key = " save* " > PROPAGATION_REQUIRED </ prop >
< prop key = " remove* " > PROPAGATION_REQUIRED </ prop >
< prop key = " get* " > PROPAGATION_REQUIRED,readOnly </ prop >
</ props >
</ property >
</ bean >
< bean id = " userManager " parent = " txProxyTemplate " >
< property name = " target " >
< bean class = " subject.service.impl.UserManagerImpl " >
< property name = " userDao " ref = " userDao " />
</ bean >
</ property >
</ bean >
<!-- Struts -->
< bean name = " /user " class = " subject.web.action.UserAction " singleton = " false " >
< property name = " userManager " >
< ref bean = " userManager " />
</ property >
</ bean >
上面具体的不用了解,无非就是调用和数据库的操作,下面就要对Acegi进行声明了:我不用Ctrl+c和Ctrl+V的方式对Acegi进行介绍,没有意义,随便google就一大堆,我们想主要在这样的系统中需要的安全策略都有哪些?
1 .用户的登陆
2 .防止多个用户登陆一个帐号
3 .用户的注销
4 .防止非法用户的访问
我这个程序所涉及到的只有这些,下面就进行说明:
在web.xml的声明:
<!-- Acegi安全控制 Filter 配置 -->
< filter >
< filter - name > securityFilter </ filter - name >
< filter - class > org.acegisecurity.util.FilterToBeanProxy </ filter - class >
< init - param >
< param - name > targetClass </ param - name >
< param - value > org.acegisecurity.util.FilterChainProxy </ param - value >
</ init - param >
</ filter >
< filter - mapping >
< filter - name > securityFilter </ filter - name >
< url - pattern > /**/ /* </url-pattern>
</filter-mapping>
Acegi通过实现了Filter接口的FilterToBeanProxy提供一种特殊的使用Filter的方式,它委托Spring中的Bean -- FilterChainProxy来完成过滤功能,这样就简化了web.xml的配置,并且利用Spring IOC的优势。FilterChainProxy包含了处理认证过程的filter列表,每个filter都有各自的功能。
<!-- ======================== FILTER CHAIN ======================= -->
< bean id = " filterChainProxy " class = " org.acegisecurity.util.FilterChainProxy " >
< property name = " filterInvocationDefinitionSource " >
< value >
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**/ /* *=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,
securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor
</value>
</property>
</bean>
大体上先介绍一下:
httpSessionContextIntegrationFilter:每次request前 HttpSessionContextIntegrationFilter从Session中获取Authentication对象,在request完后, 又把Authentication对象保存到Session中供下次request使用,此filter必须其他Acegi filter前使用,使之能跨越多个请求。
logoutFilter:用户的注销
authenticationProcessingFilter:处理登陆请求
exceptionTranslationFilter:异常转换过滤器
filterInvocationInterceptor:在访问前进行权限检查
这些就犹如在web.xml声明一系列的过滤器,不过当把他们都声明在spring中就可以享受Spring给我们带来的方便了。
下面就是对这些过滤器的具体声明:
只对有用的地方进行声明,别的地方几乎都是默许的
<!-- ======================== FILTER ======================= -->
< bean id = " httpSessionContextIntegrationFilter " class = " org.acegisecurity.context.HttpSessionContextIntegrationFilter " />
< bean id = " logoutFilter " class = " org.acegisecurity.ui.logout.LogoutFilter " >
< constructor - arg value = " /index.htm " /> // 离开后所转向的位置
< constructor - arg >
< list >
< bean class = " org.acegisecurity.ui.logout.SecurityContextLogoutHandler " />
</ list >
</ constructor - arg >
< property name = " filterProcessesUrl " value = " /logout.htm " /> // 定义用户注销的地址,
</ bean >
下面的这个过滤器处理登陆请求,我们根据自己的需求有了自己的实现:
< bean id = " authenticationProcessingFilter " class = " subject.web.filter.UserAuthenticationProcessingFilter " >
< property name = " authenticationManager " ref = " authenticationManager " />
< property name = " authenticationFailureUrl " value = " /login.htm?error=wrong " /> // 登陆失败的地址
< property name = " defaultTargetUrl " value = " /login.htm " /> // 登陆成功的地址
< property name = " filterProcessesUrl " value = " /j_security_check " /> // 登陆请求的地址
< property name = " userManager " ref = " userManager " /> // 自己添加的属性,这样就可以访问到我们的业务逻辑
< property name = " exceptionMappings " > // 出现异常所对应的地址
< value >
org.acegisecurity.AuthenticationException =/ login.htm ? error = fail 登陆失败
org.acegisecurity.concurrent.ConcurrentLoginException =/ login.htm ? error = too 已登陆了
</ value >
</ property >
</ bean >
作用未知 :
< bean id = " securityContextHolderAwareRequestFilter " class = " org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter " />
异常转换过滤器
< bean id = " exceptionTranslationFilter " class = " org.acegisecurity.ui.ExceptionTranslationFilter " >
< property name = " authenticationEntryPoint " >
< bean class = " org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint " > //进行表单认证;
<property name = " loginFormUrl " value = " /login.htm?error=please " /> // 如果用户没登陆就想访问,先到这里登陆吧
<property name = " forceHttps " value = " false " />
</bean >
</property >
</bean >
在访问前进行权限检查
< bean id = " filterInvocationInterceptor " class = " org.acegisecurity.intercept.web.FilterSecurityInterceptor " >
< property name = " authenticationManager " ref = " authenticationManager " /> 认证服务
< property name = " accessDecisionManager " >
< bean class = " org.acegisecurity.vote.AffirmativeBased " >
< property name = " allowIfAllAbstainDecisions " value = " false " />
< property name = " decisionVoters " >
< list >
< bean class = " org.acegisecurity.vote.RoleVoter " >
// 这里定义数据库中存放的角色和我们在这里声明的角色间是否需要加个前缀?我没加
< property name = " rolePrefix " value = "" />
</ bean >
</ list >
</ property >
</ bean >
</ property >
< property name = " objectDefinitionSource " >
< value >
PATTERN_TYPE_APACHE_ANT
/ admin.htm *= a 这里就是数据库中对应的tyep a
/ student *= s 由于没有前缀和数据库里一样
/ teacher *= t
</ value >
</ property >
</ bean >
记录事件
< bean id = " loggerListener " class = " org.acegisecurity.event.authentication.LoggerListener " />
下面就要说明我们的认证服务了,其起到的关键作用就是用来保证用户登陆身份的验证:
它将验证的功能委托给多个Provider,并通过遍历Providers, 以保证获取不同来源的身份认证,若某个Provider能成功确认当前用户的身份,authenticate()方法会返回一个完整的包含用户授权信息的Authentication对象,否则会抛出一个AuthenticationException。
先声明一个管理器吧,在上面的过滤器中都已经用到过了
<!-- ======================== AUTHENTICATION ======================= -->
< bean id = " authenticationManager " class = " org.acegisecurity.providers.ProviderManager " >
< property name = " providers " >
< list >
// 我仅仅用到 从数据库中读取用户信息验证身份
< ref local = " daoAuthenticationProvider " />
</ list >
</ property >
< property name = " sessionController " >
< bean id = " concurrentSessionController "
class = " org.acegisecurity.concurrent.ConcurrentSessionControllerImpl " >
< property name = " maximumSessions " >
< value > 1 </ value > // 每个用户同时登陆一位
</ property >
< property name = " sessionRegistry " >
< bean id = " sessionRegistry " class = " org.acegisecurity.concurrent.SessionRegistryImpl " />
</ property >
< property name = " exceptionIfMaximumExceeded " value = " true " />
</ bean >
</ property >
</ bean >
来实现唯一的一个Provider,从数据库验证身份
< bean id = " daoAuthenticationProvider " class = " org.acegisecurity.providers.dao.DaoAuthenticationProvider " >
< property name = " userDetailsService " >
< bean id = " jdbcDaoImpl "
class = " org.acegisecurity.userdetails.jdbc.JdbcDaoImpl " >
< property name = " dataSource " ref = " dataSource " />
< property name = " usersByUsernameQuery " >
< value >
// 查找用户的查询语句,只需要把你数据库中的用户和密码以及enable相对应上就行
select user,password,about from user where user = ?</ value >
</ property >
< property name = " authoritiesByUsernameQuery " >
< value >
// 这里就是把用户和权限对应上,在appfuse中用的两个表,
// 我都放一个表里了,
// 所以就用这一个就行问题的关键是要让它能找到两个字段,构成一个对象
select user,type from user where user = ?
</ value >
</ property >
</ bean >
</ property >
< property name = " userCache " > // 缓存都这么写:
< bean class = " org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache " >
< property name = " cache " >
< bean class = " org.springframework.cache.ehcache.EhCacheFactoryBean " >
< property name = " cacheManager " >
< bean class = " org.springframework.cache.ehcache.EhCacheManagerFactoryBean " />
</ property >
< property name = " cacheName " value = " userCache " />
</ bean >
</ property >
</ bean >
</ property >
</ bean >
==============
对于上面登陆请求的处理器我借鉴了springSide,实现的方法如下:
package subject.web.filter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
import org.acegisecurity.userdetails.UserDetails;
import subject.Constants;
import subject.model.User;
import subject.service.UserManager;
public class UserAuthenticationProcessingFilter extends
AuthenticationProcessingFilter
{
private UserManager userManager;
public void setUserManager( UserManager userManager )
{
this .userManager = userManager;
}
protected boolean requiresAuthentication( HttpServletRequest request ,
HttpServletResponse response )
{
boolean requiresAuth = super.requiresAuthentication( request, response );
HttpSession httpSession = null ;
try
{
httpSession = request.getSession( false );
}
catch ( IllegalStateException ignored )
{
}
if ( httpSession != null )
{
if ( httpSession.getAttribute( Constants.USER ) == null )
{
if ( ! requiresAuth )
{
SecurityContext sc = SecurityContextHolder.getContext();
Authentication auth = sc.getAuthentication();
if ( auth != null
&& auth.getPrincipal() instanceof UserDetails )
{
UserDetails ud = (UserDetails) auth.getPrincipal(); // 上面声明的sql无非就是要包装成这个对象
User user = userManager.getUser( ud.getUsername() );从业务逻辑里找到用户,放到session里
httpSession.setAttribute( Constants.USER, user );
}
}
}
}
return requiresAuth;
}
}
在看看我的login.htm在登陆成功时是怎么工作的吧?
public class UserAction extends BaseAction
{
private UserManager mgr;
public void setUserManager( UserManager mgr )
{
this .mgr = mgr;
}
public ActionForward login( ActionMapping mapping , ActionForm form ,
HttpServletRequest request , HttpServletResponse response )
throws Exception
{
User user = (User) getSessionObject( request, Constants.USER );
ActionMessages msg = new ActionMessages();
if ( user != null )
{
return new ActionForward( user.getType() + " .htm " , true );成功就去type.htm
}
else
{
String error = getParameter( request, Constants.ERROR );
if ( error != null )对于不同的错误,都加以提示
{
if ( error.equalsIgnoreCase( " wrong " ) )
msg.add( " msg " , new ActionMessage( " fail.login.wrong " ) );
else if ( error.equalsIgnoreCase( " too " ) )
msg.add( " msg " , new ActionMessage( " fail.login.too " ) );
else if ( error.equalsIgnoreCase( " fail " ) )
msg.add( " msg " , new ActionMessage( " fail.login.fail " ) );
else
msg.add( " msg " , new ActionMessage( " fail.login.please " ) );
}
else
msg.add( " msg " , new ActionMessage( " fail.login.please " ) );
}
saveErrors( request, msg );
return mapping.findForward( " fail " );
}
}
当然,Acegi需要介绍的东西太多了,我只把我这次认为有必要解释的东西写在了上面让大家来参考,作为能google到的东西,比如对于认证的方式还有很多,我就没有详细的介绍,在学习Acegi过程中,把它自带的例子弄清楚很关键,希望大家一起学习一起共勉!
发表评论
-
spring ioc 原理 spring aop原理
2010-06-10 14:09 71361.关于spring ioc 这段 ... -
spring aop控制权限,想要细到method级别
2008-11-26 12:38 2589spring aop控制权限,想要细到method级别,但是a ... -
Spring2.0简明手册(系列之三 AOP-1.x)aop cglib
2008-10-28 15:05 1630Spring2.0简明手册(系列之三 AOP-1.x) - ... -
CGlib简单介绍
2008-09-28 16:30 185505-11 (转)CGlib简单介绍 原文:http://ww ...
相关推荐
多目标白鲸优化算法MOBWO:在多目标测试函数中的实证与应用分析,多目标白鲸优化算法MOBWO的实证研究:在九个测试函数中的表现与评估,多目标白鲸优化算法MOBWO 在9个多目标测试函数中测试 Matlab语言 程序已调试好,可直接运行,算法新颖 1将蛇优化算法的优良策略与多目标优化算法框架(网格法)结合形成多目标蛇优化算法(MOSO),为了验证所提的MOSO的有效性,将其在9个多目标测试函数 (ZDT1、ZDT2、ZDT3、ZDT4、ZDT6、Kursawe、Poloni,Viennet2、Viennet3) 上实验,并采用IGD、GD、HV、SP四种评价指标进行评价,部分效果如图1所示,可完全满足您的需求~ 2源文件夹包含MOBWO所有代码(含9个多目标测试函数)以及原始白鲸优化算法文献 3代码适合新手小白学习,一键运行main文件即可轻松出图 4仅包含Matlab代码,后可保证原始程序运行~ ,多目标白鲸优化算法(MOBWO); 测试函数; Matlab语言; 程序调试; 算法新颖; 多目标蛇优化算法(MOSO); IGD、GD、HV、SP评价指标; 代码学习; 轻松出图。,基于
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
内容概要:本文介绍了在中国石油勘探开发梦想云平台上定义REST API接口的基本规范,旨在提高接口质量,便于开发、测试和维护。主要内容包括REST API的基础概念,设计流程,URI、HTTP方法及响应状态码的运用,API文档的管理以及Swagger工具的应用,还详细阐述了API安全认证,特别是JWT的应用。通过这份文档能够帮助开发者理解和实施高质量的微服务架构。 适用人群:适用于参与或计划参与微服务项目的开发团队,尤其是那些致力于提升REST API接口质量和效率的专业技术人员。 使用场景及目标:文档的目标在于引导用户理解REST API接口设计的关键要素,如资源命名、方法选择等,并教会他们如何有效管理和保护这些API,确保其稳定性和安全性。通过实践本指南的原则,用户可以构建出更加健壮的分布式应用程序接口。 其他说明:此外,文中提供了大量关于API文档生成与维护的最佳做法,强调了文档更新须与代码同步,同时也探讨了API变更管理的有效方法。在安全方面,重点讲述了JWT的构成及其工作机制,展示了利用JWT实现高效认证的具体实例。
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
内容概要:该文档详细介绍了基于双向长短期记忆(BiLSTM)神经网络与Adaboost集成学习的时间序列预测模型及其应用。文中阐述了项目背景,指出了传统LSTM在复杂数据下存在的局限,提出了通过BiLSTM增强前后依赖关系,并结合Adaboost优化模型精度与泛化能力的方法。全文涵盖了从数据预处理、特征提取到建模、评估、以及GUI设计在内的全过程,并展示了该模型在金融预测、气象预报、能源管理和生产调度等多个领域的广泛应用潜力。文章还包括对代码片段的具体解析、模型部署的考量及未来发展的展望。 适合人群:拥有基本的机器学习与神经网络基础的研究人员和技术开发者,尤其是那些正在寻找时间序列数据分析解决方案的专业人士。 使用场景及目标:1. 多个领域如金融市场、气象预测等的时间序列数据处理任务中;2. 解决传统单一神经网络可能出现的过拟合并优化模型的鲁棒性和准确性。 其他说明:除了详细讲解如何使用Matlab实施完整的BiLSTM和Adaboost集成外,文中还特别注意到了模型调优的重要性——通过超参数搜索、早停策略和其他正则化技巧以预防过拟合情况的发生。此外,文档还讨论了有关实时数据处理、模型安全性和可移植性的要点。附带完整的Matlab代码实现了从环境准备直到预测结果可视化的每一个步骤,使读者可以很容易地复现和定制整个工作流程。
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
内容概要:Go 1.24 版本引入了多项关键改进,其中包括:泛型类型别名,允许类型别名携带类型参数,简化代码实现;弱指针避免对象因包含在缓存中而无法被释放的问题;改进了终结器,提供了新的运行时函数 AddCleanup 以增强对象清理的灵活性和可靠性。另外,Go 1.24 改善了 map 的默认实现,显著提升了其运行时性能。与此同时,开源项目 miniblog 是一个功能全面、易于理解的 Go 实战项目。该项目采用了类似 Kubernetes 的三层架构设计,涵盖了许多 Go 项目开发的最佳实践和技术栈,不仅有助于开发者理解 Go 项目的核心理念和实施方法,还能提供一系列开发脚手架工具、配套课程和支持材料,以便更轻松地开展实际项目。 适合人群:1年以上 Go 开发经验的研发人员或正在寻找优秀 Go 项目充实自己简历的技术人员。 使用场景及目标:该总结的目标是帮助有一定 Go 基础的知识分子迅速了解新特性及其实用价值。miniblog 项目特别适用于希望加深对 Go 实践认识的学习者,尤其是那些想要通过参与实际编码练习和深入理解 Go 内部工作机制的人群。通过这两个方面的内容学习可以帮助使用者更好地理解 Go 新增特性的应用前景和发展方向,并能够在实践中灵活应用。 其他说明:本文档不仅涵盖了新特性的技术和理论要点,同时也展示了如何通过动手实践强化技能的具体例子。阅读本文不仅可以学到最新的 Go 编程技巧,还将了解到实际开发过程中面临的挑战及其解决方案。此外,还提供了一份详细的安装指导,以及一些常见的操作指南。对于新手而言,可以通过提供的完整配套资料逐步建立起个人的知识体系;而对于资深开发者,则可以在更高层次上审视自身项目的架构设计,进而推动技术创新和个人职业发展。
CoW项目是基于大模型的智能对话机器人,支持微信公众号、企业微信应用、飞书、钉钉接入,可选择GPT3.5/GPT4.0/Claude/Gemini/LinkAI/ChatGLM/KIMI/文心一言/讯飞星火/通义千问/LinkAI,能处理文本、语音和图片,通过插件访问操作系统和互联网等外部资源,支持基于自有知识库定制企业AI应用。 功能如下: 1、 多端部署: 有多种部署方式可选择且功能完备,目前已支持微信公众号、企业微信应用、飞书、钉钉等部署方式 2、 基础对话: 私聊及群聊的消息智能回复,支持多轮会话上下文记忆,支持 GPT-3.5, GPT-4o-mini, GPT-4o, GPT-4, Claude-3.5, Gemini, 文心一言, 讯飞星火, 通义千问,ChatGLM-4,Kimi(月之暗面), MiniMax, GiteeAI 3、 语音能力: 可识别语音消息,通过文字或语音回复,支持 azure, baidu, google, openai(whisper/tts) 等多种语音模型 4、 图像能力: 支持图片生等
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
CSDN Matlab武动乾坤上传的资料均是完整代码运行出的仿真结果图,可见完整代码亲测可用,适合小白; 1、完整的代码内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
海神之光上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
基于LabVIEW的滚动轴承故障诊断系统:一种振动信号采集与故障诊断的实用设计与实践验证,基于LabVIEW的滚动轴承高效故障诊断系统设计与应用研究,基于LabVIEW的滚动轴承故障诊断系统. 实现对滚动轴承工作状态的监测,提出了一种基于 Lab VIEW 的滚动轴承故障诊断系统的设计方案,给出了滚动轴承振动信号的采集与故障诊断方法,在 Lab VIEW 的诊断平台下进行信号处理与分析,然后结合滚动轴承故障诊断理论与信号分析结果来对该轴承运行状态进行判断。 最后利用旋转机械振动及故障模拟试验平台对该系统进行验证,验证结果体现了该系统具有可行性和适用性。 ,LabVIEW; 滚动轴承故障诊断系统; 振动信号采集; 故障诊断方法; 信号处理与分析; 验证测试; 可行性; 适用性,基于LabVIEW的滚动轴承故障诊断系统设计与验证
Javascript语言视频教程,涵盖Javascript语言基础和高级教程,零基础入门。
python在链表的前面-开头插入一个节点
CSDN Matlab武动乾坤上传的资料均是完整代码运行出的仿真结果图,可见完整代码亲测可用,适合小白; 1、完整的代码内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描博客文章底部QQ名片; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
《基于改进动态窗口DWA模糊自适应调整权重的路径规划算法研究及其MATLAB实现》,《基于改进动态窗口DWA的模糊自适应权重调整路径规划算法及其MATLAB实现》,基于改进动态窗口 DWA 模糊自适应调整权重的路径基于改进动态窗口 DWA 模糊自适应调整权重的路径规划算法 MATLAB 源码+文档 《栅格地图可修改》 基本DWA算法能够有效地避免碰撞并尽可能接近目标点,但评价函数的权重因子需要根据实际情况进行调整。 为了提高DWA算法的性能,本文提出了一种改进DWA算法,通过模糊控制自适应调整评价因子权重,改进DWA算法的实现过程如下: 定义模糊评价函数。 模糊评价函数是一种能够处理不确定性和模糊性的评价函数。 它将输入值映射到模糊隶属度,根据规则计算输出值。 在改进DWA算法中,我们定义了一个三输入一输出的模糊评价函数,输入包括距离、航向和速度,输出为权重因子。 [1]实时调整权重因子。 在基本DWA算法中,权重因子需要根据实际情况进行调整,这需要人工干预。 在改进DWA算法中,我们通过模糊控制实现自适应调整,以提高算法的性能。 [2]评估路径。 通过路径的长度和避障情况等指标评估路
基于MATLAB平台PCA算法的人脸识别系统:程序调试成功,可替换数据获取高准确率识别结果,基于MATLAB平台PCA算法的人脸识别系统:程序调试与自我数据替换实现高精度识别结果,基于MATLAB平台PCA的人脸识别,程序已调通,可将自己的数据替进行识别。 得到识别准确率结果。 ,基于MATLAB平台PCA的人脸识别; 程序已调通; 数据替换; 识别准确率。,MATLAB平台PCA人脸识别程序:调通后实现高准确率识别