近期对Spring+Security的框架进行了一些简单的研究,将研究的结果贴出来,供大家学习参考。
废话少说,还是代码来的直接明了。
首先需要一些相关的源代码:
MyAccessDecisionManager.java:
/** * */ package com.simonsw.security; import java.util.Collection; import java.util.Iterator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** * @author Simon Lv * @since Oct 31, 2013 */ public class MyAccessDecisionManager implements AccessDecisionManager { private Logger logger = LoggerFactory.getLogger(getClass()); /* * (non-Javadoc) * * @see * org.springframework.security.access.AccessDecisionManager#decide(org. * springframework.security.core.Authentication, java.lang.Object, * java.util.Collection) */ @Override public void decide(Authentication authentication, Object obj, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if (configAttributes == null) { return; } // 所请求的资源拥有的权限(一个资源对多个权限) Iterator<ConfigAttribute> iterator = configAttributes.iterator(); while (iterator.hasNext()) { ConfigAttribute configAttribute = iterator.next(); // 访问所请求资源所需要的权限 String needPermission = configAttribute.getAttribute(); logger.debug("[MyAccessDecisionManager] needPermission is " + needPermission); // 用户所拥有的权限authentication for (GrantedAuthority ga : authentication.getAuthorities()) { logger.debug("[MyAccessDecisionManager] ga.getAuthority() is " + ga.getAuthority()); if (needPermission.contains((ga.getAuthority()))) { return; } } } // 没有权限让我们去捕捉 throw new AccessDeniedException(" 没有权限访问!"); } /* * (non-Javadoc) * * @see * org.springframework.security.access.AccessDecisionManager#supports(org * .springframework.security.access.ConfigAttribute) */ @Override public boolean supports(ConfigAttribute arg0) { return true; } /* * (non-Javadoc) * * @see * org.springframework.security.access.AccessDecisionManager#supports(java * .lang.Class) */ @Override public boolean supports(Class<?> arg0) { return true; } }
MyAuthenticationManager.java:
/** * */ package com.simonsw.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; 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 com.simonsw.base.entity.Resource; import com.simonsw.base.entity.Role; import com.simonsw.base.entity.RoleResource; import com.simonsw.base.entity.UserRole; import com.simonsw.base.entity.Users; import com.simonsw.base.service.RoleResourceService; import com.simonsw.base.service.UserRoleService; import com.simonsw.base.service.UserService; import com.simonsw.common.util.StringUtils; /** * @author Simon Lv * @since Oct 31, 2013 */ public class MyAuthenticationManager implements UserDetailsService { @Autowired private UserService userService; @Autowired private UserRoleService userRoleService; @Autowired private RoleResourceService roleResourceService; private Logger logger = LoggerFactory.getLogger(getClass()); /* * (non-Javadoc) * * @see org.springframework.security.core.userdetails.UserDetailsService# * loadUserByUsername(java.lang.String) */ @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { logger.debug("[MyAuthenticationManager] username ==> " + username); if (!StringUtils.isEmpty(username)) { throw new UsernameNotFoundException("用户名不能为空!"); } Users user = userService.getUserByName(username); Collection<GrantedAuthority> grantedAuths = obtionGrantedAuthorities(user); boolean enables = true; boolean accountNonExpired = true; boolean credentialsNonExpired = true; boolean accountNonLocked = true; // 封装成spring security的user User userdetail = new User(user.getUsername(), user.getPassword(), enables, accountNonExpired, credentialsNonExpired, accountNonLocked, grantedAuths); return userdetail; } // 取得用户的权限 private Set<GrantedAuthority> obtionGrantedAuthorities(Users user) { Set<GrantedAuthority> authSet = new HashSet<GrantedAuthority>(); List<Resource> resources = new ArrayList<Resource>(); Role role; List<RoleResource> roleResources; List<UserRole> userRoles = userRoleService.getUserRoleByUserId(user); for (UserRole userRole : userRoles) { role = userRole.getRole(); roleResources = roleResourceService.getUserRoleByRoleId(role); for (RoleResource roleResource : roleResources) { resources.add(roleResource.getResource()); } } for (Resource res : resources) { authSet.add(new SimpleGrantedAuthority(res.getModelname())); } return authSet; } }
MyLogoutSuccessHandler.java:
/** * */ package com.simonsw.security; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; /** * @author Simon Lv * @since Nov 5, 2013 */ public class MyLogoutSuccessHandler implements LogoutSuccessHandler { private Logger logger = LoggerFactory.getLogger(getClass()); /* * (non-Javadoc) * * @see * org.springframework.security.web.authentication.logout.LogoutSuccessHandler * #onLogoutSuccess(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, * org.springframework.security.core.Authentication) */ @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { if (authentication != null) { logger.debug(authentication.getName() + "Logout==>"); } response.sendRedirect(request.getContextPath()); } }
MySecurityFilter.java:
/** * */ package com.simonsw.security; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; /** * @author Simon Lv * @since Oct 31, 2013 */ public class MySecurityFilter extends AbstractSecurityInterceptor implements Filter { private Logger logger = LoggerFactory.getLogger(getClass()); // 与applicationContext-security.xml里的myFilter的属性securityMetadataSource对应, // 其他的两个组件,已经在AbstractSecurityInterceptor定义 private FilterInvocationSecurityMetadataSource securityMetadataSource; /* * (non-Javadoc) * * @see * org.springframework.security.access.intercept.AbstractSecurityInterceptor * #obtainSecurityMetadataSource() */ @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } /* * (non-Javadoc) * * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, * javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } private void invoke(FilterInvocation fi) throws IOException, ServletException { logger.debug("[MySecurityFilter] 用户发送请求!"); InterceptorStatusToken token = null; token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() { return securityMetadataSource; } public void setSecurityMetadataSource( FilterInvocationSecurityMetadataSource securityMetadataSource) { this.securityMetadataSource = securityMetadataSource; } /* * (non-Javadoc) * * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ @Override public void init(FilterConfig arg0) throws ServletException { } /* * (non-Javadoc) * * @see javax.servlet.Filter#destroy() */ @Override public void destroy() { } /* * (non-Javadoc) * * @see * org.springframework.security.access.intercept.AbstractSecurityInterceptor * #getSecureObjectClass() */ @Override public Class<?> getSecureObjectClass() { // 下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误 return FilterInvocation.class; } }
MySecurityMetadataSource.java:
/** * */ package com.simonsw.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import com.simonsw.base.entity.Role; import com.simonsw.base.entity.RoleResource; import com.simonsw.base.entity.UserRole; import com.simonsw.base.entity.Users; import com.simonsw.base.service.RoleResourceService; import com.simonsw.base.service.UserRoleService; import com.simonsw.base.service.UserService; /** * @author Simon Lv * @since Oct 31, 2013 */ public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource { @Autowired protected UserService userService; @Autowired protected UserRoleService userRoleService; @Autowired protected RoleResourceService roleResourceService; private Logger logger = LoggerFactory.getLogger(getClass()); private static LinkedHashMap<String, Collection<ConfigAttribute>> resourceMap = null; /* * (non-Javadoc) * * @see * org.springframework.security.access.SecurityMetadataSource#getAttributes * (java.lang.Object) */ @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String requestURL = ((FilterInvocation) object).getRequestUrl(); logger.debug("[MySecurityMetadataSource] 请求地址 ===> " + ((FilterInvocation) object).getRequestUrl()); if (null == resourceMap) { loadResourceDefine(); logger.debug("[MySecurityMetadataSource] 我需要的认证 ==> " + resourceMap.toString()); } for (Map.Entry<String, Collection<ConfigAttribute>> entry : resourceMap .entrySet()) { logger.debug("[MySecurityMetadataSource] entry.getKey() ===> " + entry.getKey()); logger.debug("[MySecurityMetadataSource] request ===> " + requestURL); if (entry.getKey().equals(requestURL)) { return entry.getValue(); } } return null; } /** * Load all resource */ private void loadResourceDefine() { resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>(); Map<String, String> resource = getResource(); for (Map.Entry<String, String> entry : resource.entrySet()) { Collection<ConfigAttribute> configAttributes = new ArrayList<ConfigAttribute>(); configAttributes.add(new SecurityConfig(entry.getValue())); resourceMap.put(entry.getKey(), configAttributes); } } /** * 加载所有资源与权限的关系 * * @return */ private Map<String, String> getResource() { Map<String, String> resourceMap = new HashMap<String, String>(); List<Users> users = userService.findAll(); List<UserRole> userRoles; Role role; List<RoleResource> roleResources; userfor: for (Users user : users) { logger.debug("userId => " + user.getUserid()); userRoles = userRoleService.getUserRoleByUserId(user); if (userRoles == null) { logger.debug("userfor => break!!!!"); break userfor; } rolefor: for (UserRole userRole : userRoles) { role = userRole.getRole(); roleResources = roleResourceService.getUserRoleByRoleId(role); if (roleResources == null) { break rolefor; } for (RoleResource roleResource : roleResources) { String url = roleResource.getResource().getValue(); if (!resourceMap.containsKey(url)) { resourceMap.put(url, role.getName()); } else { String roleName = resourceMap.get(url); resourceMap.put(url, roleName + "," + role.getName()); } } } } return resourceMap; } /* * (non-Javadoc) * * @see org.springframework.security.access.SecurityMetadataSource# * getAllConfigAttributes() */ @Override public Collection<ConfigAttribute> getAllConfigAttributes() { // TODO Auto-generated method stub return null; } /* * (non-Javadoc) * * @see * org.springframework.security.access.SecurityMetadataSource#supports(java * .lang.Class) */ @Override public boolean supports(Class<?> arg0) { // TODO Auto-generated method stub return true; } }
MyUsernamePasswordAuthenticationFilter.java:
/** * */ package com.simonsw.security; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import com.simonsw.base.entity.Users; import com.simonsw.base.service.UserService; import com.simonsw.common.util.CipherUtil; import com.simonsw.common.util.StringUtils; /** * @author Simon Lv * @since Oct 31, 2013 */ public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Autowired protected UserService userService; private Logger logger = LoggerFactory.getLogger(getClass()); public static final String VALIDATE_CODE = "validateCode"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) { if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException( "Authentication method not supported: " + request.getMethod()); } // checkValidateCode(request); String username = obtainUsername(request); logger.debug("[MyUsernamePasswordAuthenticationFilter] username ==> "+ username); String password = CipherUtil.generatePassword(obtainPassword(request)); logger.debug("[MyUsernamePasswordAuthenticationFilter] password ==> "+ password); // 验证用户账号与密码是否对应 username = username.trim(); Users users = userService.getUserByName(username); if (users == null || !users.getPassword().equals(password)) { throw new AuthenticationServiceException( "password or username is notEquals"); } // UsernamePasswordAuthenticationToken实现 Authentication UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken( username, password); // Place the last username attempted into HttpSession for views // 允许子类设置详细属性 setDetails(request, authRequest); // 运行UserDetailsService的loadUserByUsername 再次封装Authentication return this.getAuthenticationManager().authenticate(authRequest); } protected void checkValidateCode(HttpServletRequest request) { HttpSession session = request.getSession(); String sessionValidateCode = obtainSessionValidateCode(session); // 让上一次的验证码失效 session.setAttribute(VALIDATE_CODE, null); String validateCodeParameter = obtainValidateCodeParameter(request); if (StringUtils.isEmpty(validateCodeParameter) || !sessionValidateCode.equalsIgnoreCase(validateCodeParameter)) { throw new AuthenticationServiceException("validateCode.notEquals"); } } private String obtainValidateCodeParameter(HttpServletRequest request) { Object obj = request.getParameter(VALIDATE_CODE); return null == obj ? "" : obj.toString(); } protected String obtainSessionValidateCode(HttpSession session) { Object obj = session.getAttribute(VALIDATE_CODE); return null == obj ? "" : obj.toString(); } @Override protected String obtainUsername(HttpServletRequest request) { Object obj = request.getParameter(USERNAME); return null == obj ? "" : obj.toString(); } @Override protected String obtainPassword(HttpServletRequest request) { Object obj = request.getParameter(PASSWORD); return null == obj ? "" : obj.toString(); } }
具体的security.xml配置信息:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns:beans="http://www.springframework.org/schema/beans" xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <debug /> <global-method-security pre-post-annotations="enabled" /> <!-- 此目录下不需要过滤 --> <http pattern="/js/**" security="none" /> <http pattern="/css/**" security="none" /> <http pattern="/images/**" security="none" /> <http pattern="/login" security="none" /> <http use-expressions="true" entry-point-ref="authenticationProcessingFilterEntryPoint"> <!-- if no limit, go to 403 page --> <access-denied-handler error-page="/403" /> <!-- Logout --> <logout invalidate-session="true" logout-url="/logout" success-handler-ref="myLogoutSuccessHandler" /> <!-- 实现免登陆验证 --> <remember-me /> <session-management invalid-session-url="/"> <concurrency-control max-sessions="10" error-if-maximum-exceeded="true" /> </session-management> <custom-filter ref="loginFilter" position="FORM_LOGIN_FILTER" /> <custom-filter ref="securityFilter" before="FILTER_SECURITY_INTERCEPTOR" /> </http> <!-- 登录验证器 --> <beans:bean id="loginFilter" class="com.simonsw.security.MyUsernamePasswordAuthenticationFilter"> <!-- 处理登录 --> <beans:property name="filterProcessesUrl" value="/user/login"></beans:property> <beans:property name="authenticationSuccessHandler" ref="loginLogAuthenticationSuccessHandler"></beans:property> <beans:property name="authenticationFailureHandler" ref="simpleUrlAuthenticationFailureHandler"></beans:property> <beans:property name="authenticationManager" ref="myAuthenticationManager" /> </beans:bean> <beans:bean id="loginLogAuthenticationSuccessHandler" class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"> <beans:property name="defaultTargetUrl" value="/"></beans:property> </beans:bean> <beans:bean id="simpleUrlAuthenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <beans:property name="defaultFailureUrl" value="/"></beans:property> </beans:bean> <!-- 认证过滤器 --> <beans:bean id="securityFilter" class="com.simonsw.security.MySecurityFilter"> <!-- 用户拥有的权限 --> <beans:property name="authenticationManager" ref="myAuthenticationManager" /> <!-- 用户是否拥有所请求资源的权限 --> <beans:property name="accessDecisionManager" ref="myAccessDecisionManager" /> <!-- 资源与权限对应关系 --> <beans:property name="securityMetadataSource" ref="mySecurityMetadataSource" /> </beans:bean> <!-- 实现了UserDetailsService的Bean --> <authentication-manager alias="myAuthenticationManager"> <authentication-provider user-service-ref="myAuthenticationManagers" /> </authentication-manager> <beans:bean id="myAccessDecisionManager" class="com.simonsw.security.MyAccessDecisionManager"></beans:bean> <beans:bean id="mySecurityMetadataSource" class="com.simonsw.security.MySecurityMetadataSource"> </beans:bean> <beans:bean id="myAuthenticationManagers" class="com.simonsw.security.MyAuthenticationManager"> </beans:bean> <beans:bean id="myLogoutSuccessHandler" class="com.simonsw.security.MyLogoutSuccessHandler" /> <!-- 未登录的切入点 --> <beans:bean id="authenticationProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"> <beans:property name="loginFormUrl" value="/login"></beans:property> </beans:bean> </beans:beans>
最后一定要在web.xml中配置加上:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-security.xml</param-value> </context-param>
<!-- Spring Security Session --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener> <!-- Spring security Filter --> <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>
启动Tomcat,登录正常工作。
具体想看源代码,请访问GitHub网站上的源代码:
https://github.com/simon5408/DummyProj
顺便说一下,得到源代码以后,需要数据库支持,具体的数据库结构及数据请看附件。
相关推荐
Spring Security 是一个强大的且高度可定制的...总之,Spring Security 3.1.3配置实例提供了对用户认证、授权、安全控制的实践操作,通过理解并应用这些配置,开发者可以有效地保护自己的应用程序免受潜在的安全威胁。
这个"spring-security-3.1.3.RELEASE-dist.zip"压缩包包含了Spring Security 3.1.3版本的所有源码、库文件和其他相关资源,使得开发者能够深入理解其工作原理并进行定制化开发。 首先,Spring Security的核心概念...
这个压缩包包含的是Spring Security 3.1.3版本的所有jar文件,是该框架的一个完整集合,适用于那些希望在项目中集成Spring Security 3.1.3版本的开发者。 Spring Security 提供了全面的安全解决方案,包括但不限于...
3. **配置Hibernate**:设置Hibernate的配置文件,包括数据库连接信息、方言、缓存策略等,并在Spring配置文件中引入SessionFactory bean。 4. **整合Struts2与Spring**:使用Struts2的Spring插件,使Struts2的动作...
在Spring Security 3.1.3中,配置主要通过XML进行,尽管从4.0版本开始,Spring Security引入了基于Java的配置,使得配置更加直观和灵活。在案例中,我们可能会看到如何设置`<http>`元素来定义安全拦截规则,以及如何...
SpringSecurity3.1.3 + JDK1.7 + Maven3.3.3 + Jetty9,提供基本的pom.xml,applicationContext.xml,web.xml配置和jetty插件的配置
springSecurity springSecurity3.1.3
本话题将深入探讨Spring Security的3.0.0和3.1.3两个版本,这两个版本都是该框架历史上的重要里程碑。 Spring Security 3.0.0是Spring Security发展的一个关键阶段,引入了大量新特性与改进。此版本加强了对Spring ...
这个压缩包提供了Spring Security 3.1.3的源码,以及一个名为"sample"的示例项目,帮助开发者理解和学习如何在实际应用中使用这个库。 **1. Spring Security的基本架构** Spring Security基于过滤器链的概念,其...
《深入解析Spring Security 3.1.3.RELEASE》 Spring Security是Java领域中一个强大的安全框架,它为Web应用程序提供了全面的安全性解决方案。本文将深入探讨Spring Security 3.1.3.RELEASE版本的核心特性、工作原理...
Spring Security的配置可以通过XML或者Java配置来完成,3.1.3 RELEASE版本引入了更多的Java配置选项,使得配置更加简洁直观。开发者可以根据需求定制安全链路、认证和授权策略。 四、安全表达式(Security ...
3. **spring-security-config-3.1.3.RELEASE.jar**:配置模块允许开发者通过XML或Java配置来声明式地定义安全规则。它使用Spring的Bean定义来构建安全配置,包括访问控制、用户细节服务和安全元数据源等。 4. **...
文件管理器+_3.1.3_-1616136748.apk
jUI富客户端1.4.6+ThinkPHP3.1.3 重新整合版添加头导航,权限管理,分页审核等,应用云引擎,此外将tpm也整合其中,近期会发布tpm简单教程。 用户名:admin 密码 :admin 此用户为最高权限,希望大家不要随意删除...
【VS2015+Python3.4+R3.1.3混合编程】这篇文章主要介绍了如何在Visual Studio 2015 (VS2015)环境下搭建Python和R的混合编程环境,使得开发者可以在同一开发环境中同时利用Python和R的优势。 首先,VS2015社区版是...
通过在Spring配置文件中定义`<http>`、`<authentication-manager>`等元素,或使用`@EnableGlobalAuthentication`、`@Secured`等注解,可以方便地配置安全策略。 4. **spring-security-ldap-3.1.3.RELEASE.jar**:这...
【DWZ 1.4.6 + ThinkPHP 3.1.3 开发模板】是将DWZ(Dynamic Web Zone)框架与ThinkPHP 3.1.3框架结合的开发资源,旨在为开发者提供一个高效、便捷的Web应用开发环境。这个组合允许开发者利用DWZ的前端交互功能和...
《Spring Security 3.1.3.RELEASE:构建安全的Java Web应用》 Spring Security是Java平台上一个强大的安全框架,广泛应用于构建企业级的Web应用程序。这个版本——3.1.3.RELEASE,是该框架的一个稳定版本,为开发者...
Docker(Hadoop_3.3.1+HBase_2.4.16+Zookeeper_3.7.1+Hive_3.1.3 )配置文件 搭建集群环境