`
yzxqml
  • 浏览: 134871 次
  • 性别: Icon_minigender_1
  • 来自: 广西
文章分类
社区版块
存档分类
最新评论

Spring security初探

阅读更多



    现在很多企业和开发团队都使用了SSH2(Struts 2 +Spring 2.5 +Hibernate)框架来进行开发,  我们或许已经习惯了强大的Spring Framework 全局配置管理,不可否认,Sping是一个很优秀的开源框架,但是由于Spring3.0版本后强大的的注解式bean的诞生,Spring MVC框架这匹黑马正悄然杀起,但今天Spring MVC不是主角,今天我和大家分享一个同样隶属于SpringSource 的安全框架——Spring Security, 下面的基于Spring MVC给大家分享一下Spring Security  的使用。虽然对它的接触时间不长,参考了一些网上朋友的做法,但也按照我的理解把这个框架介绍介绍,不是很专业,还请大家不要介意 。

    

     我们知道,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个资源来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

 

     首先,我们看web.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<!--	编码统一最好放最上面,最先加载,防止乱码-->
	<filter>
		<filter-name>Set Character Encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value><!-- 强制进行转码 -->
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>Set Character Encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- 然后接着是SpringSecurity必须的filter 优先配置,让SpringSecurity先加载,防止SpringSecurity拦截失效-->
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<!--	
	spring需要加载的配置文件
-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value> 
 	WEB-INF/classes/applicationContext.xml,
 	WEB-INF/spring3-servlet.xml,
 	WEB-INF/spring-security.xml 
		</param-value>
	</context-param>

	<listener>
		<listener-class>
			<!--		所以,要在web.xml下面配置好监听,让服务器启动时就初始化改类,可以得到request	-->
			org.springframework.web.context.request.RequestContextListener
		</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>


	<!--
		默认所对应的配置文件是WEB-INF下的{servlet-name}-servlet.xml,这里便是:spring3-servlet.xml
	-->
	<servlet>
		<servlet-name>spring3</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>

	</servlet>

	<servlet-mapping>
		<servlet-name>spring3</servlet-name>
		<!--
			这里可以用 / 但不能用 /*
			,拦截了所有请求会导致静态资源无法访问,所以要在spring3-servlet.xml中配置mvc:resources
		-->
		<url-pattern>/</url-pattern>
	</servlet-mapping>



</web-app>

 

     

 

    注释已经写了挺多,还是稍微解释一下要注意的地方,一个是UTF-8编码转换,这个最好加在最前面,让它先生效,我在调试的时候就出过这种情况,web.xml里的其他配置都正常生效了,但是编码死活不行,一中文就乱码,郁闷了老半天,然后突发奇想,是不是web.xml里先声明的配置先生效,后声明的后生效?接着实践,果然不出我所料,把编码转换加在前面,一切正常。。。。我那个晕。。。

 

 

 

关于Spirng MVC的就不说了,那些数据访问、业务和控制层那些的东东就自个研究去了吧。。这不是今天的重点。

 

 接着是spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	   		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
			http://www.springframework.org/schema/security 
			http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<!--  Spring-Security 的配置 -->
	<!--
		注意use-expressions=true.表示开启表达式,否则表达式将不可用. see:http://www.family168.com/tutorial/springsecurity3/html/el-access.html
	-->
	<security:http auto-config="true" use-expressions="false" access-denied-page="/user/login_failure.html">
		<!--允许所有人访问-->
		<!--		<security:intercept-url pattern="/**" access="permitAll" />-->
		<!--允许ROLE_ADMIN权限访问-->
		<security:intercept-url pattern="/user/findAll.html" access="ROLE_ADMIN" />
		<!--允许ROLE_ADMIN权限访问-->
		<security:intercept-url pattern="/user/**" access="ROLE_ADMIN" />
		<!--允许ROLE_USER权限访问-->
		<security:intercept-url pattern="/success.jsp" access="ROLE_USER,ROLE_ADMIN" />
		<!--允许IS_AUTHENTICATED_ANONYMOUSLY匿名访问-->
		<security:intercept-url pattern="/anonymously.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
		
		<!-- filters="none"  不过滤这些资源-->
		<security:intercept-url pattern="/js/**" filters="none" />
		<security:intercept-url pattern="/index.jsp" filters="none" />

		<!-- login-page:默认指定的登录页面. authentication-failure-url:出错后跳转页面. default-target-url:成功登陆后跳转页面 -->
		<security:form-login login-page="/index.jsp" authentication-failure-url="/user/login_failure.html"
			default-target-url="/success.jsp" />
		<!--
			invalidate-session:指定在退出系统时是否要销毁Session。logout-success-url:退出系统后转向的URL。logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。
		-->
		<security:logout invalidate-session="true" logout-success-url="/index.jsp" logout-url="/j_spring_security_logout" />
		<!--
			max-sessions:允许用户帐号登录的次数。范例限制用户只能登录一次。exception-if-maximum-exceeded:
			默认为false,此值表示:用户第二次登录时,前一次的登录信息都被清空。当exception-if-maximum-exceeded="true"时系统会拒绝第二次登录。
		-->

		<security:session-management>
			<security:concurrency-control error-if-maximum-exceeded="true" max-sessions="1" />
		</security:session-management>

	</security:http>
	<!-- 指定一个自定义的authentication-manager :customUserDetailsService -->
	<security:authentication-manager>
		<security:authentication-provider user-service-ref="customUserDetailsService">
			<security:password-encoder ref="passwordEncoder" />
		</security:authentication-provider>
	</security:authentication-manager>

	<!-- 对密码进行MD5编码 -->
	<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />

	<!-- 
		通过 customUserDetailsService,Spring会控制用户的访问级别.
		也可以理解成:以后我们和数据库操作就是通过customUserDetailsService来进行关联.
	 -->
	<bean id="customUserDetailsService" class="org.yzsoft.springmvcdemo.util.CustomUserDetailsService" />
	<!--	自定义登陆错误提示,可以取出mymessages.properties的国际化消息-->
	<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
		<property name="basename" value="classpath:org/yzsoft/springmvcdemo/mymessages" />
	</bean>
	<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver" />
</beans>

  

 

 这个多解释一下,首先

 

	<security:intercept-url pattern="/findAll.html" access="hasRole('ROLE_ADMIN')" />
        <security:intercept-url pattern="/user/**" access="hasRole('ROLE_ADMIN')" />
        <security:intercept-url pattern="/anonymously.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />

 这个是权限控制,声明了拥有什么权限可以访问哪些资源,这个配置的是有ROLE_ADMIN权限的才可以访问/findAll.html,至于这个ROLE_ADMIN从哪来,呆会再解释。或者像第二句一样配置也可以:拥有ROLE_ADMIN权限的才可以访问/user/下的所有资源,否则都会抛AccessDeniedException 。

IS_AUTHENTICATED_ANONYMOUSLY就是匿名访问的意思,这个相信都懂的。。。

 

然后是登陆和安全退出

<security:form-login login-page="/index.jsp" authentication-failure-url="/user/login_failure.html"default-target-url="/user/findAll.html" />
<security:logout invalidate-session="true" logout-success-url="/index.jsp" logout-url="/user/login_failure.html" />

 解释下上面一句,相信看也能看出来了的,login-page:默认指定的登录页面. authentication-failure-url:出错后跳转页面(包括那些个啥用户名密码错误吖。。啥啥啥的。). default-target-url:成功登陆后跳转页面 (这里我直接跳到的控制器去查数据列表)。   

 

 接着:invalidate-session:指定在退出系统时是否要销毁Session。logout-success-url:退出系统后转向的URL。logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。

 

接下来是一个比较不错的功能:是否允许同一用户多处登陆

<security:session-management>
	 <security:concurrency-control error-if-maximum-exceeded="true" max-sessions="1" />
</security:session-management>

exception-if-maximum-exceeded:
   默认为false,此值表示:用户第二次登录时,前一次的登录信息都被清空。当error-if-maximum-exceeded="true"时系统会拒绝第二次登录。 

max-sessions:允许用户帐号登录的次数,这里我们允许一次登陆。这里我们做个实验吧,看看是不是真的生效了,请看图


 

 

这里我们看到,当同一个账号多处登陆时,就会报出Maximum sessions of 1 for this principal exceeded 的错误,当然,正式使用我们换成mymessages.properties里的我们自定义的国际化消息,这样人性化一点。
 

 好,我们往下看,接着就是应用我们实际项目里的自定义用户权限了

<security:authentication-manager>
	 <security:authentication-provider user-service-ref="customUserDetailsService">
		 <security:password-encoder ref="passwordEncoder" />
	 </security:authentication-provider>
</security:authentication-manager>

	<!-- 对密码进行MD5编码 -->
<bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<bean id="customUserDetailsService" class="org.yzsoft.springmvcdemo.util.CustomUserDetailsService" />

 首先是<security:authentication-manager>是指定我们自定义的身份验证策略,这里我们用customUserDetailsService这个bean,就是指向我们CustomUserDetailsService.java这个类。然后<security:password-encoder>指定我们密码使用MD5进行编码,调用Spring Security自带的MD5加密类。当然,还有加盐MD5或我们自己写的加密算法等安全性更加高的密码策略。这个按项目实际使用配置吧。

 

然后看到我们的CustomUserDetailsService.java

package org.yzsoft.springmvcdemo.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.yzsoft.springmvcdemo.serviceimpl.UsersServiceImpl;
import org.yzsoft.springmvcdemo.vo.TUsers;

/**
 * 一个自定义的类用来和数据库进行操作. 即以后我们要通过数据库保存权限.则需要我们继承UserDetailsService
 * 
 * @author 
 * 
 */
public class CustomUserDetailsService implements UserDetailsService {

	protected static Logger logger = Logger.getLogger("service");//log4j,不用解释了吧。。
	@Autowired
	private UsersServiceImpl usersService;

	public UsersServiceImpl getUsersService() {
		return usersService;
	}

	public void setUsersService(UsersServiceImpl usersService) {
		this.usersService = usersService;
	}

	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {

		UserDetails user = null;

		try {

			// 搜索数据库以匹配用户登录名.
			// 我们可以通过dao使用Hibernate来访问数据库
			System.out.println(username + "   用户页面输入的用户名");
			TUsers tusers = this.usersService.findByUsername(username);
			System.out.println(tusers.getUsername() + "   数据库取出的用户名");
			// Populate the Spring User object with details from the dbUser
			// Here we just pass the username, password, and access level
			// getAuthorities() will translate the access level to the correct
			// role type
			// 用户名、密码、是否启用、是否被锁定、是否过期、权限
			user = new User(tusers.getUsername(), tusers.getPassword().toLowerCase(), true, true, true, true, getAuthorities(Integer.parseInt(tusers.getRole())));
			 
			 
		} catch (Exception e) {
			logger.error("用户信息错误!");
			throw new UsernameNotFoundException("异常处理:检索用户信息未通过!");
		}
		 
		return user;
	}

	/**
	 * 获得访问角色权限列表
	 * 
	 * @param access
	 * @return
	 */
	public Collection<GrantedAuthority> getAuthorities(Integer role) {
		System.out.println("取得的权限是  :" + role);
		List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();

		// 所有的用户默认拥有ROLE_USER权限
		if (role == 0) {
			System.out.println("普通用户");
			logger.debug("取得普通用户权限-->");
			authList.add(new GrantedAuthorityImpl("ROLE_USERS"));
		}
		// 如果参数role为1.则拥有ROLE_ADMIN权限
		if (role == 1) {
			logger.debug("取得ADMIN用户权限-->");
			authList.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
		}
		System.out.println(authList.size()+"  权限列表长度");
		return authList;
	}
}

 这里就是把我们从数据库里面取得的用户权限和Spring Security的配置进行桥接,还记得上面配置文件里的ROLE_ADMIN吧,就是从这里来的,很奇怪的是,这个必须设置成ROLE_ 开头才有效。。郁闷。。。

这里我刚开始有一个疑惑,我们看这2句

TUsers tusers = this.usersService.findByUsername(username);
user = new User(tusers.getUsername(), tusers.getPassword().toLowerCase(), true, true, true, true, getAuthorities(Integer.parseInt(tusers.getRole())));

 这里根本不需要用户输入的密码,只要了用户名,然后直接根据用户名去取权限,就直接设置进Spring Security的User对象里面去,我不禁一身冷汗,这不相当于说有了用户名就直接去查数据库么,而且是不用密码的。。。。

但经过查看官方文档和网上的解释,这才放心,原来是这样的,Spring Security的确是直接根据用户名去查,但是查得出来的Spring Security  User对象之后,它会根据这个对象的属性值去数据库查询与这个对象匹配的数据,我们这里设置的是(用户名,密码,是否启用、是否被锁定、是否过期、权限。。。),那么如果数据库存在这个对象,就返回真,否则返回假,这样也就不用担心了,完全可靠。就是我们在前台要做好限制,不能给用户不输密码就访问, 不然挤爆你数据库连接。。。。。

 

 

 最后登陆页面index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page"> 
  </head>
  
  <body>
    用户登陆 <br>
     ${SPRING_SECURITY_LAST_EXCEPTION.message}
      <form action="j_spring_security_check" method="post">
    	USERNAME:<input type="text" name="j_username" value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /><br/>
    	PASSWORD:<input type="password" name="j_password" value="" /><br/>
    	<input type="checkbox" name="_spring_security_remember_me" />两周之内不必登陆(这个功能没有做的)<br/>
		<input type="submit">    	
    </form>
  </body>
</html>

 

这里我还是使用Spring Security默认的j_username和j_password,表单目标也用默认的j_spring_security_check,会默认跳到Spring Security进行拦截。其他的应该不用解释了吧。。。。

 

最后 ,我们整理一下Spring Security的整个控制过程:

 

——>用户登陆

——> <security:authentication-manager> 拦截

——>交给customUserDetailsService处理,并且声明密码采用MD5策略

——>根据输入的用户名去数据库查这条记录,验证身份

——>取出该条记录的用户权限(锁定、禁用、过期和实际权限等)

——>根据取得的权限列表去security:intercept-url匹配、授权,然后判断是否放行。

这就完成了一整个的权限控制流程。

 

接下来我们来测试一下看是否真的生效了:

1、测试匿名访问页面,直接地址栏访问:

 

 

 

 

 

2、普通用户登陆



  

 

 

 

然后访问后台管理页面,跳回了登陆页



 

 

 

 

 

3、管理员用户登陆

 

 

 

 

退出后成功跳转回登陆页,点击后退再执行其他操作,这时候session已经注销了的,不能执行,又跳回了登陆页。是我们想要的效果,OK,成功了。

 

 

 好了,Spring Security的简单使用就讲到这里,其实这只是Spring Security的一小部分,而且这里我还没有用权限表对用户权限进行专门的管理,很多东西还是用Spring Security 默认的,还有Spring Security CAS (单点登陆)以及更加高级的权限控制和更完善的Spring Security 配置,以后我们再慢慢去研究吧。发现Spring Security 这个技术不仅简化了我们的用户权限管理,要知道我们做管理系统的时候这是个大问题,也差不多颠覆了我一贯以来用户权限管理的观念,但是掌握了这种思维之后,又发现,其实,程序并不是只有一种实现方式,它激发了我写程序时要去寻找多种解决方案的想法。学习的路上,就是要不断推翻自己固有的思维,去见识多种新事物,才能有进步。

 

 

 

 

 最后是项目文件,比较大,分卷了,还没有Maven的版本,以后奉上~~~

  • 大小: 70.4 KB
  • 大小: 13.9 KB
  • 大小: 17 KB
  • 大小: 23.5 KB
  • 大小: 23.5 KB
分享到:
评论
14 楼 hnaxing 2015-07-23  
你好,用这个DEMO启动就报错呀
[ERROR] [localhost-startStop-1 10:18:02] (ContextLoader.java:initWebApplicationContext:307) Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/security]
Offending resource: ServletContext resource [/WEB-INF/spring-security.xml]

	at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
	at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80)
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316)
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1416)
	at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1409)
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:140)
	at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:111)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
	at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:174)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:209)
	at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
	at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
	at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:131)
	at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:522)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:436)
	at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5016)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5528)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:722)
七月 23, 2015 10:18:02 上午 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/security]
Offending resource: ServletContext resource [/WEB-INF/spring-security.xml]
13 楼 calcyu 2015-04-27  
    
12 楼 zhl121068 2015-04-22  
大侠你好,求整个项目的源码,谢谢。zhl_1210@163.com或者1542997948@qq.com
11 楼 dbcjh 2015-04-17  
10 楼 zxf0089216 2015-03-26  
是上传有限制吗,看到9MB,9MB的真心烦
9 楼 依米艳 2015-03-03  
您好,我想问个问题。
自定义身份验证的时候,CustomUserDetailsService.java这个类里面,有这样子的一个判断
        if (role == 1) { 
            logger.debug("取得ADMIN用户权限-->"); 
            authList.add(new GrantedAuthorityImpl("ROLE_ADMIN")); 
        } 

那如果我新增了一个 role =3 配置了role_admin权限。还需要在这里面添加吗。
假设我已经有一套用户,权限功能授权模型。不能通过配置解决吗。如果可以的话,通过配置又怎么解决呢。
8 楼 jiang_huatao 2014-12-25  
缺少压缩文件包中。。
7 楼 wh2728527 2014-12-17  
能给个完整的吗?wh2728527@163.com
6 楼 jixu8 2014-12-12  
请问下下载后怎么解压不了呢。
5 楼 云端月影 2014-12-02  
我只能说:各种报错,没有办法解决呀。
4 楼 云端月影 2014-12-01  
感谢楼主的分享,学习了
3 楼 wang263574375 2014-11-05  
你不能把你的源码上传的云盘里面啊
2 楼 a295481541 2014-06-30  
 
1 楼 winner_king 2013-10-21  
[b][/b]

相关推荐

    数据库基础测验20241113.doc

    数据库基础测验20241113.doc

    微信小程序下拉选择组件

    微信小程序下拉选择组件

    DICOM文件+DX放射平片-数字X射线图像DICOM测试文件

    DICOM文件+DX放射平片—数字X射线图像DICOM测试文件,文件为.dcm类型DICOM图像文件文件,仅供需要了解DICOM或相关DICOM开发的技术人员当作测试数据或研究使用,请勿用于非法用途。

    Jupyter Notebook《基于双流 Faster R-CNN 网络的 图像篡改检测》+项目源码+文档说明+代码注释

    <项目介绍> - 基于双流 Faster R-CNN 网络的 图像篡改检测 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

    使用epf捕获没有CA证书的SSLTLS明文(LinuxAndroid内核支持amd64arm64).zip

    c语言

    (源码)基于Arduino的天文数据库管理系统.zip

    # 基于Arduino的天文数据库管理系统 ## 项目简介 本项目是一个基于Arduino的天文数据库管理系统,旨在为Arduino设备提供一个完整的天文数据库,包括星星、星系、星团等天体数据。项目支持多种语言的星座名称,并提供了详细的天体信息,如赤道坐标、视星等。 ## 项目的主要特性和功能 星座目录包含88个星座,提供拉丁语、英语和法语的缩写和全名。 恒星目录包含494颗亮度达到4等的恒星。 梅西耶目录包含110个梅西耶天体。 NGC目录包含3993个NGC天体,亮度达到14等。 IC目录包含401个IC天体,亮度达到14等。 天体信息每个天体(不包括星座)提供名称、命名、相关星座、赤道坐标(J2000)和视星等信息。 恒星额外信息对于恒星,还提供每年在赤经和赤纬上的漂移以及视差。 ## 安装使用步骤 1. 安装库使用Arduino IDE的库管理器安装本项目的库。 2. 解压数据库将db.zip解压到SD卡中。

    (源码)基于JSP和SQL Server的维修管理系统.zip

    # 基于JSP和SQL Server的维修管理系统 ## 项目简介 本项目是一个基于JSP和SQL Server的维修管理系统,旨在提供一个高效、便捷的维修管理解决方案。系统涵盖了从维修订单的创建、管理到配件的录入、更新等多个功能模块,适用于各类维修服务行业。 ## 项目的主要特性和功能 1. 用户管理 管理员和客户的注册与登录。 管理员信息的管理与更新。 客户信息的创建、查询与更新。 2. 维修订单管理 维修订单的创建、查询与更新。 维修回执单的创建与管理。 3. 配件管理 配件信息的录入与更新。 配件库存的管理与查询。 4. 评价与反馈 客户对维修服务的评价记录。 系统反馈信息的收集与管理。 5. 数据加密与安全 使用MD5加密算法对用户密码进行加密存储。 通过过滤器实现登录验证,确保系统安全。 ## 安装使用步骤

    devecostudio-windows-3.1.0.501.zip

    HUAWEI DevEco Studio,以下简称DevEco Studio)是基于IntelliJ IDEA Community开源版本打造,为运行在HarmonyOS和OpenHarmony系统上的应用和服务(以下简称应用/服务)提供一站式的开发平台。 作为一款开发工具,除了具有基本的代码开发、编译构建及调测等功能外,DevEco Studio还具有如下特点: - 高效智能代码编辑:支持ArkTS、JS、C/C++等语言的代码高亮、代码智能补齐、代码错误检查、代码自动跳转、代码格式化、代码查找等功能,提升代码编写效率。更多详细信息,请参考[编辑器使用技巧] - 低代码可视化开发:丰富的UI界面编辑能力,支持自由拖拽组件和可视化数据绑定,可快速预览效果

    《计算机视觉技术》实验报告-8.1提取车辆轮廓

    《计算机视觉技术》实验报告-8.1提取车辆轮廓

    springboot小徐影城管理系统(代码+数据库+LW)

    随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各类信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求做了介绍,并且对系统做了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。

    C++与Matlab实现SIFT特征提取算法+项目源码+文档说明+代码注释

    <项目介绍> - SIFT特征提取算法C++与Matlab实现 - 不懂运行,下载完可以私聊问,可远程教学 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

    (1991-2024年)国家自然、社科基金部分名单(含部分标书)(最新!!!)

    数据介绍 数据名称:国家自然、社科基金部分名单 数据年份:1991-2024年 样本数量:10万+ 数据格式:PDF、excel

    卓晴-信号与系统课件.pdf

    卓晴

    as-bundled-clients

    as-bundled-clients

    学习时最后的资料包括面试等信息

    学习时最后的资料包括面试等信息

    (源码)基于Spring Boot和Ant Design的雨选课系统.zip

    # 基于Spring Boot和Ant Design的雨选课系统 ## 项目简介 雨选课系统是一个基于Spring Boot和Ant Design框架构建的前后端分离的选课系统。该系统实现了学生选课、成绩查询、教师成绩修改、课程编辑、课程新增等功能。登录信息使用Redis存储,并支持课程图片的上传功能。 ## 项目的主要特性和功能 1. 用户登录与权限管理 学生、教师和管理员分别有不同的登录权限。 登录信息使用Redis进行存储。 2. 课程管理 学生可以查看可选课程列表,并进行选课和退选操作。 教师可以查看自己教授的课程,并修改学生成绩。 管理员可以编辑和新增课程。 3. 成绩管理 学生可以查询自己的成绩。 教师可以修改学生的成绩。 4. 图片上传 支持课程图片的上传和展示。 5. 日志记录 系统记录请求和响应的日志信息,便于问题追踪和性能分析。

    数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)

    数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目),含有代码注释,满分大作业资源,新手也可看懂,期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。该项目可以作为课程设计期末大作业使用,该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅点餐系统源码+数据库+文档说明(高分项目)数据库期末作业基于Python+mysql的餐厅

    江苏镇江两座小桥的技术状况评估与维修建议

    内容概要:本文针对镇江市丹徒区辛丰镇的两座小型桥梁(大叶二组滚水坝桥与东联组桥)进行了详细的技术状况评定和现状调查。主要内容包括:桥梁的基本参数描述、桥梁各部分的具体检查结果以及存在的具体病害及其原因分析,同时依据《公路桥梁技术状况评定标准》对每座桥梁分别给出了综合评分和技术状况等级,并提出了具体的维护与修复建议。大叶二组滚水坝桥技术状况良好(2类),但需要解决桥面铺装裂缝和桥墩的混凝土剥落问题;而东联组桥则需重点关注桥面施工不完整及护栏损坏等问题。 适用人群:桥梁管理人员、维护工作人员及城市基础设施规划相关人员。 使用场景及目标:适用于中小跨度桥梁的常规检查与维修决策制定过程中,旨在帮助专业人士快速掌握桥梁的实际状态,确保桥梁安全可靠运行。 其他说明:文中附有多张实拍图片用于直观展示桥梁现状及存在问题。

    基于套接字API开发的高性能高稳定性跨平台MQTT客户端,可以在嵌入式设备FreeRTOS LiteOS RTThre.zip

    c语言

    【Unity 天气系统插件】Enviro 3 - Sky and Weather 高度可定制的云、雾和光照系统

    文件名:Enviro 3 - Sky and Weather v3.1.6b.unitypackage Enviro 3 - Sky and Weather 是一款功能强大的 Unity 插件,专门用于模拟逼真的天空、天气和环境效果。它适用于需要动态天气和日夜循环的游戏或应用,如开放世界 RPG、模拟类游戏等。Enviro 3 提供了大量的设置选项和自定义功能,帮助开发者在 Unity 中创建沉浸式的自然环境效果。 以下是 Enviro 3 - Sky and Weather 的一些关键特点和功能介绍: 1. 动态天气系统 天气变化:支持多种天气效果,如晴天、阴天、雨天、雪天、雾天、暴风雨等,所有天气效果可以动态切换,使游戏环境更加生动。 天气事件:允许开发者设置特定的天气事件,如风暴、雷电等,添加到游戏中的特殊场景或事件。 湿度与温度控制:可以根据天气变化动态控制湿度和温度,影响环境效果和玩家体验。 2. 日夜循环系统 动态时间系统:Enviro 3 支持实时的日夜循环,包括昼夜的过渡,太阳和月亮的运动轨迹。 光照调整:随着时间变化,Enviro 3 会自动调整环境光、

Global site tag (gtag.js) - Google Analytics