- 浏览: 102175 次
- 性别:
- 来自: 北海
最新评论
-
July01:
最近了解到一款StratoIO打印控件,功能如下:1、Html ...
IE下利用js实现打印功能 -
sunxiyuan111:
试了第三种方法 ,管用,解决了大问题谢谢
jasperreports导出pdf报表时粗体的显示问题 -
java爱好者92:
主子报表帆软报表官网上的攻略说得很详细,可以参考一下
利用iReport制作子报表 -
fengjianquan9527:
狗屁不通,毛用不管
jasperreports导出pdf报表时粗体的显示问题 -
xiegqooo:
codeloafer 写道现在activemq5.6 以上ne ...
ActiveMQ集群应用
先看一下spring security 官方对以下几个类或接口的解释,因为这个几个类在程序中会使用到;
ConfigAttribute:Stores a security system related configuration attribute.
SecurityConfig:ConfigAttribute的实现类。
GrantedAuthority:Represents an authority granted to an Authentication object.
GrantedAuthorityImpl:GrantedAuthority的实现类。
UserDetails:Provides core user information.
Authentication:Represents the token for an authentication request or for an authenticated principal once the request has been processed by the AuthenticationManager.authenticate(Authentication) method.
UserDetailsService:Core interface which loads user-specific data.
FilterInvocationSecurityMetadataSource:Marker interface for SecurityMetadataSource implementations that are designed to perform lookups keyed on FilterInvocations.
AccessDecisionManager:Makes a final access control (authorization) decision.
定义四张表:用户表、角色表、资源表、组织机构表(可选)
首先需要在web.xml文件中添加以下配置:
<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>
接着配置spring security的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" 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.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- access-denied-page:定义没有权限时跳转的页面 ;use-expressions:true表示使用表达式定义忽略拦截资源列表--> <http auto-config="true" access-denied-page="/accessDenied.do" use-expressions="true"> <!-- 忽略拦截资源定义 --> <intercept-url pattern="/showLogin.do*" filters="none" /> <intercept-url pattern="/scripts/**" filters="none" /> <intercept-url pattern="/images/**" filters="none" /> <intercept-url pattern="/styles/**" filters="none" /> <intercept-url pattern="/dwr/**" filters="none" /> <!-- isAuthenticated()表示只有通过验证的用户才能访问 --> <intercept-url pattern="/**" access="isAuthenticated()" /> <intercept-url pattern="/main.do*" access="isAuthenticated()" /> <!-- max-sessions=1:禁止2次登陆;ession-fixation-protection="none":防止伪造sessionid攻击,用户登录成功后会销毁用户当前的session,--> <!-- 创建新的session并把用户信息复制到新session中 ;invalid-session-url:定义session超时跳转页面 --> <session-management invalid-session-url="/timeout.jsp" session-fixation-protection="none"> <concurrency-control max-sessions="1" /> </session-management> <!-- 表单验证 --> <form-login login-page="/showLogin.do" authentication-failure-url="/showLogin.do?error=true" always-use-default-target="true" default-target-url="/login.do?error=false" /> <!-- 退出系统跳转页面 --> <logout invalidate-session="true" logout-success-url="/showLogin.do" /> <!-- 免登陆验证 --> <remember-me /> <!-- 自定义拦截器(这里和spring security2的配置有点不同) --> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="securityFilter" /> </http> <beans:bean id="securityFilter" class="xxx.xxx.xxx.commons.permissionengine.web.security.FilterSecurityInterceptor"> <beans:property name="authenticationManager" ref="authenticationManager" /> <beans:property name="accessDecisionManager" ref="securityAccessDecisionManager" /> <beans:property name="securityMetadataSource" ref="securityMetadataSource" /> </beans:bean> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref="securityUserDetailService"> <!-- 密码采用MD5算法加密 --> <password-encoder hash="md5" /> </authentication-provider> </authentication-manager> <!-- 用户拥有的权限 --> <beans:bean id="securityUserDetailService" class="xxx.xxx.xxx.commons.permissionengine.web.security.SecurityUserDetailService" /> <!-- 用户是否拥有所请求资源的权限 --> <beans:bean id="securityAccessDecisionManager" class="xxx.xxx.xxx.commons.permissionengine.web.security.SecurityAccessDecisionManager" /> <!-- 资源与权限对应关系 --> <beans:bean id="securityMetadataSource" class="xxx.xxx.xxx.commons.permissionengine.web.security.SecurityMetadataSource" /> </beans:beans>
接着需要写一个类实现UserDetails接口,这个并不是我们系统的用户,它只是一个VO,
用于保存从spring security上下文环境中获取到登录用户,因为从spring security上下文环境中获取登录用户的返回值就是UserDetails的实现类:
package xxx.xxx.xxx.commons.permissionengine.entity; import java.util.Collection; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class UserDetailInfo implements UserDetails { private static final long serialVersionUID = 6137804370301413132L; private String userName; private String password; private Collection<GrantedAuthority> authorities; public UserDetailInfo() {} @Override public Collection<GrantedAuthority> getAuthorities() { return authorities; } @Override public String getPassword() { return password; } @Override public String getUsername() { return userName; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public void setPassword(String password) { this.password = password; } public void setAuthorities(Collection<GrantedAuthority> authorities) { this.authorities = authorities; } }
接着自定义一个继承了AbstractSecurityInterceptor的filter:
package xxx.xxx.xxx.commons.permissionengine.web.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.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; public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { private FilterInvocationSecurityMetadataSource securityMetadataSource; @Override public void destroy() { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { FilterInvocation invocation = new FilterInvocation(request, response, filterChain); invoke(invocation); } public void invoke(FilterInvocation filterInvocation) throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(filterInvocation); try { filterInvocation.getChain().doFilter(filterInvocation.getRequest(), filterInvocation.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } @Override public Class<? extends Object> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) { this.securityMetadataSource = securityMetadataSource; } public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() { return this.securityMetadataSource; } }
接着定义一个类,实现了UserDetailsService接口,主要用于获取登录用户信息和用户所具有的角色
package xxx.xxx.xxx.commons.permissionengine.web.security; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import javax.annotation.Resource; import org.springframework.dao.DataAccessException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import xxx.xxx.xxx.commons.permissionengine.entity.Role; import xxx.xxx.xxx.commons.permissionengine.entity.User; import xxx.xxx.xxx.commons.permissionengine.entity.UserDetailInfo; import xxx.xxx.xxx.commons.permissionengine.service.IUserService; public class SecurityUserDetailService implements UserDetailsService { private IUserService userService; /** * 获取登录用户信息并添加到security上下文环境 */ @Override public UserDetails loadUserByUsername(String name)throws UsernameNotFoundException, DataAccessException { //定义存放用户角色信息的集合 Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); //通过已经经过验证的登录用户的用户名查找登录用户信息 User user = userService.findUserByProperty("name", name); //定义一个userDetailInfo对象,该类实现了spring security UserDetails接口,因为已经经过验证的登录用户会保持在 //spring security上下文环境中,通过该上下文环境获取登录用户信息返回的是UserDetails类型,因此需要定义一个类实现该接口 UserDetailInfo userDetailInfo = null; if(user != null) { //获取登录用户信息的角色列表 Set<Role> roles = user.getRoles(); for(Role role : roles) { //利用角色用户具有的角色的编号构造一个GrantedAuthority对象,并把该对象添加到集合中 GrantedAuthorityImpl grantedAuthorityImpl = new GrantedAuthorityImpl("ROLE_"+role.getNo()); authorities.add(grantedAuthorityImpl); } userDetailInfo = new UserDetailInfo(); userDetailInfo.setUserName(user.getName()); userDetailInfo.setPassword(user.getPassword()); //把角色信息添加到userDetailInfo对象中 userDetailInfo.setAuthorities(authorities); } return userDetailInfo; } @Resource(name = "userService") public void setUserService(IUserService userService) { this.userService = userService; } }
再接着定义一个实现了FilterInvocationSecurityMetadataSource的类:
package xxx.xxx.xxx.commons.permissionengine.web.security; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.annotation.Resource; 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 org.springframework.security.web.util.AntUrlPathMatcher; import org.springframework.security.web.util.UrlMatcher; import xxx.xxx.xxx.commons.permissionengine.service.IMenuService; /** * 资源源数据管理器 * @author Keven * */ public class SecurityMetadataSource implements FilterInvocationSecurityMetadataSource { private IMenuService menuService; //定义一个url匹配工具类 private UrlMatcher urlMatcher = new AntUrlPathMatcher(); private static Map<String, Collection<ConfigAttribute>> menuMap = null; //该构造方法由spring容器调用 public SecurityMetadataSource() { loadMenuDefine(); } private void loadMenuDefine() { menuMap = new HashMap<String, Collection<ConfigAttribute>>(); //初始化匿名用户所拥有的权限 Collection<ConfigAttribute> guestAtts = new ArrayList<ConfigAttribute>(); ConfigAttribute guestAttribute = new SecurityConfig("ROLE_Guest"); guestAtts.add(guestAttribute); menuMap.put("/showLogin.do*", guestAtts); } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { //获取请求url String url = ((FilterInvocation)object).getRequestUrl(); //从数据库获取资源与角色的对应关系,并设置初始化的资源_角色到该Map menuService.setMenuMap(menuMap); //获取资源列表 Iterator<String> iter = menuMap.keySet().iterator(); while(iter.hasNext()) { String menuUrl = iter.next(); //防止把null值加入到map,报空指针异常 if(menuUrl != null) { //请求url与角色所拥有的权限做匹配 if(urlMatcher.pathMatchesUrl(menuUrl, url)) return menuMap.get(menuUrl); } } return null; } @Override public boolean supports(Class<?> clazz) { return true; } @Resource(name = "menuService") public void setMenuService(IMenuService menuService) { this.menuService = menuService; } }
再接着定义一个实现了AccessDecisionManager的类:
package xxx.xxx.xxx.commons.permissionengine.web.security; import java.util.Collection; import java.util.Iterator; import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.SecurityConfig; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** * 决策管理器,用于判断用户需要访问的资源与用户所拥有的角色是否匹配 * @author Keven * */ public class SecurityAccessDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes == null) return; //获取资源与角色对应关系列表 Iterator<ConfigAttribute> iter = configAttributes.iterator(); while(iter.hasNext()) { ConfigAttribute configAttribute = iter.next(); //获取访问该资源需要的角色 String needRole = ((SecurityConfig)configAttribute).getAttribute(); //从上下文环境获取用户所具有的角色 for(GrantedAuthority grantedAuthority : authentication.getAuthorities()) { //判断用户拥有的角色是否与访问该资源所需要的角色匹配 if(needRole.equals(grantedAuthority.getAuthority())) return; } } throw new AccessDeniedException("权限不足!"); } @Override public boolean supports(ConfigAttribute arg0) { return true; } @Override public boolean supports(Class<?> arg0) { return true; } }
spring security的基本的登录认证和授权就这样完成了,有关spring security的方法和领域对象的权限控制、单点登录和分布式登录请看下集。
评论
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。
你的安全元数据里面的构造函数逻辑是去数据库把角色对应的资源全部加载到内存,那现在数据量很大,速度很慢怎么办?
另外问你下,loadMenuDefine方法是在系统启动时一次性加载的,进入系统更改了对应关系权限和菜单的关系后,系统不能立即反应过来,你是如何处理的呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。
你的安全元数据里面的构造函数逻辑是去数据库把角色对应的资源全部加载到内存,那现在数据量很大,速度很慢怎么办?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
肯定存在,不存在就没法做到访问控制。
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
补充:在你的上下文里面是存在是否具有这个authority的逻辑的, 如果用户直接访问地址,访问被拒绝。
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
菜单是赋值给有这个链接地址权限的用户的,那么是不存在你说的这个问题了。
说白了 我说的菜单就是url,但最终用户知道的只是菜单。
你觉得呢?
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
对~这里面已经包含了访问控制
要是只过滤菜单的话其实是不安全的,菜单里面的url要是被人知道的也可以访问,所以控制菜单不是绝对的安全。
发表评论
-
cas客户端应用实现
2011-12-20 15:51 6717cas服务器端的开发请参考: http://xiaomage ... -
cas+tomcat开发单点登录教程(定制认证方式篇)
2011-12-19 20:43 10368CAS 是 Yale 大学发起的 ... -
java开发webservice的几种方式
2011-12-17 15:33 10816webservice的应用已经越来 ... -
compass搜索引擎的应用
2011-09-12 11:29 2767前阵子在做一个手机服务器端系统的开发,主要使用spring+h ... -
EJB系统使用JMS异步发送邮件
2011-01-26 15:58 2097EJB中有三种Bean,EntityBean,SessionB ... -
jasperreports导出pdf报表时粗体的显示问题
2010-12-23 17:14 6566最近一直在做报表,用的是iReport3.7.3和jasper ... -
利用iReport制作子报表
2010-12-10 16:09 5795iReport版本:3.7.3,JavaBean作为数据源。1 ... -
解决GET提交中文乱码问题
2010-11-19 15:20 2661今天同事在做一个手机 ... -
IE下利用js实现打印功能
2010-10-29 11:08 3615这主要是用到了IE的一个内置插件,在html代码的<he ... -
struts2+jasperReport生成各种形式的报表
2010-10-28 17:10 2880/** * 導出html形式報表 * @param r ... -
利用js给select element产生年份
2010-10-25 16:32 2659function generateYearFun() { v ... -
解决struts2+jasperReport在生成html形式的报表时的图片问题
2010-10-18 14:09 3502Struts2和jasperReport整合时,在生成html ... -
struts2 java.lang.IllegalStateException异常的解决方法
2010-10-15 18:46 4932环境:eclipse+struts2+EJB3.0+jaspe ... -
Tomcat JVM调优有感
2010-09-25 22:42 2134最近在做一个社交类网 ... -
struts2+ajax做的一个级联下拉列表
2010-09-20 14:47 2669struts2+ajax做的一个级联下拉列表 struts端代 ... -
struts2+jsonplugin的问题
2010-09-15 00:16 1303[size=xx-small]今天做项目碰到了个问题,在做一个 ... -
关于embed标签的src属性
2010-09-05 16:47 1869前阵子做个项目,需要把用户上传的pdf文件转换为swf文件然后 ... -
ssh与jbpm4.3的整合
2010-05-28 20:23 1475首先说一下环境,spring3.0+struts2+hiber ...
相关推荐
Spring Security 是一...总之,Spring Security 3.0提供了一套完整的安全解决方案,其核心组件包括了认证、授权、Web安全和对象级别的权限控制。理解和掌握这些jar包的功能,能够帮助开发者有效地构建安全的应用程序。
Spring Security 3.0提供了强大的权限控制功能,通过合理设计数据库结构、实体模型以及精心配置,可以实现灵活且安全的应用程序权限管理。对于那些希望深入理解并掌握Spring Security 3.0权限控制的开发者而言,以上...
本教程将深入探讨SpringSecurity3.0的核心概念、配置及其实现方式,帮助开发者理解并掌握如何在Java应用中实现强大的安全防护。 一、SpringSecurity概述 SpringSecurity是一个开源项目,其主要目标是为Java应用提供...
在这个"spring security3.0 demo"中,开发者可能会展示如何创建用户、角色、权限,如何配置安全拦截规则,以及如何实现登录、登出功能。这个示例将帮助初学者理解Spring Security的基本用法和配置,以便在实际项目中...
虽然OAuth2不是Spring Security 3.0.x 的核心部分,但Spring Security 提供了对OAuth2的支持,方便与外部服务进行身份验证和授权。 ### 9. 安全Web服务 Spring Security 提供了对Web服务(如SOAP和RESTful)的安全...
在本项目"SpringSecurity3.0 Demo"中,我们将深入探讨SpringSecurity 3.0版本的功能和用法。 首先,SpringSecurity的核心功能包括用户认证(Authentication)和权限授权(Authorization)。在3.0版本中,它引入了更...
标题 "springMVC+springSecurity3.0+maven" 指的是一个集成项目,它结合了Spring MVC、Spring Security 3.0和Maven这三个关键的Java开发工具和技术。让我们逐一深入理解这些技术及其相互之间的关系。 首先,Spring ...
总结,Spring Security 3.0 的权限管理系统为开发者提供了一套全面的工具,从用户认证到复杂授权策略的实施,帮助企业构建安全的软件环境。了解和掌握这些核心概念和组件,将有助于开发者构建更加健壮和安全的应用...
在Spring Security 3.0版本中,这个框架进行了大量的改进和增强,以适应不断变化的安全需求。 Spring Security的核心概念包括: 1. **过滤器链**:这是Spring Security的主要执行机制,它通过一系列自定义的过滤器...
Spring Security是基于Spring框架的一个强大的、可高度定制的安全框架,主要用在Java平台上,用于为应用提供认证和授权。Spring Security 3.0是该框架的一个重要版本,提供了许多安全控制功能,用于保护Web应用程序...
认证与授权是Spring Security的核心功能。认证主要是指通过用户提供的凭证(通常是用户名和密码)来确认用户身份,一旦认证成功,Spring Security会创建一个安全上下文,包含用户的详细信息,如用户名、密码、角色和...
《Spring 3.0 + Spring Security 3.1.4 API 中文版》是一份集成了Spring框架3.0和Spring Security 3.1.4的中文帮助文档,旨在为开发者提供详尽的API参考和指导。这两个核心组件在企业级Java应用开发中扮演着至关重要...
<html xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"> <h1>Welcome, <sec:authentication property="principal.username"/></h1> ``` ##### 4. 实现方法级安全 在方法级别添加安全...
Spring Security 2.0 提供了基础的认证和授权功能,而3.0进一步强化了模块化设计。这使得开发者可以根据项目需求选择合适的组件,如Web安全模块、方法安全模块和密码存储模块等。 2. **表达式式访问控制...
在Spring Security 3.0中,我们可以使用预定义的认证和授权机制,如基于角色的访问控制(RBAC),或者自定义策略来满足特定需求。 5. **过滤器链** Spring Security的核心是过滤器链,它处理每个HTTP请求。过滤器...
《Spring Security 3.0 GA 入门与深入解析》 Spring Security 是一款强大的安全框架,广泛应用于Java Web 应用程序的安全管理。在3.0 GA版本中,该框架进一步提升了性能,优化了API,并增加了许多新特性,使得安全...
Struts2与Spring Security的集成可以帮助实现Web层的请求过滤,确保只有经过验证和授权的用户才能访问特定的Action。 整合这四个框架,首先需要配置Spring Security来处理用户的登录和权限控制。这通常涉及创建安全...
《SpringSecurity_3.0》是一本面向Java Web开发初学者和中级程序员的教程,它深入浅出地介绍了Spring Security这一强大的安全框架。Spring Security是一个为Java应用提供身份验证和授权服务的开源项目,它旨在保护...
例如,`spring-security-core`负责基本的认证和授权逻辑,`spring-security-web`处理与Web安全相关的请求过滤,而`spring-security-config`则简化了在Spring应用上下文中定义安全规则的过程。 使用时,开发者可以...