spring security学习笔记

spring security
配置过滤器
首先要在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-2.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
</beans:beans>

基本配置
<!--定义认证管理器-->
<authentication-manageralias="authenticationManager" />
<authentication-manageralias="authenticationManager"
         session-controller-ref="concurrentSessionController"/>
<beans:beanid="sessionRegistry"
    class="org.springframework.security.concurrent.SessionRegistryImpl"/>
<beans:beanid="concurrentSessionController"
    class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
    <beans:propertyname="maximumSessions" value="1" />
    <beans:propertyname="exceptionIfMaximumExceeded" value="false" />
    <beans:propertyname="sessionRegistry" ref="sessionRegistry" />
</beans:bean>

<http auto-config='true'lowercase-comparisons="false"
      access-denied-page="/System/Login.action?error=true">
   <intercept-urlpattern="/System/Login.action" filters="none" />
   <intercept-urlpattern="/System/Login!logout.action" filters="none"/>
   <form-loginlogin-page="/System/Login.action"
        default-target-url="/System/Login!login.action"
        login-processing-url="/System/j_login_check"
        authentication-failure-url="/System/Login.action"
        always-use-default-target="true"/>
   <concurrent-session-control expired-url="/System/Login.action" max-sessions="1" />
   <logout logout-success-url="/System/Login!logout.action" invalidate-session="true"
      logout-url="/System/j_spring_security_logout"/>
</http>

<!--认证数据提供者-->
<authentication-provideruser-service-ref="userDetailsService" />
<beans:beanid="userDetailsService" class="com.***.security.UserDetailsServiceImpl">
   <beans:propertyname="***" ref="UsermCache" />
   <beans:propertyname="***" ref="UserRoleCache"/>
   <beans:propertyname=***" ref="UserMenuCache"/>      
</beans:bean>

<!--访问决策管理器-->
<beans:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
    <beans:propertyname="decisionVoters">
        <beans:list>
            <beans:bean class="org.springframework.security.vote.RoleVoter">
                 <beans:propertyname="rolePrefix" value="ROLE_" />
            </beans:bean>
        </beans:list>
    </beans:property>
</beans:bean>

<!--过滤器安全拦截器,检查authentication所授予的权限是否可以访问被访问的资源-->
<beans:beanid="filterSecurityInterceptor" class="com.***.security.RefreshResources">
    <!--覆盖http配置中的intercept-url的配置-->
    <custom-filterbefore="FILTER_SECURITY_INTERCEPTOR" />
    <beans:propertyname="authenticationManager" ref="authenticationManager"/>
    <beans:propertyname="accessDecisionManager" ref="accessDecisionManager"/>
    <beans:propertyname="PermissionService"ref="PermissionService" />
</beans:bean>

<beans:beanid="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <beans:property name="basename" value="classpath:com/***/web/action/system/LoginAction"/>
</beans:bean>
<beans:bean id="localeResolver"   class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>

 
配置好的AuthenticationManager会处理每个认证请求。如果认证失败,浏览器会重定向到authenticationFailureUrl。AuthenticationException会被放到HttpSession中,属性名是AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,在错误页里为用户提供一个出错原因。
 

maximumSessions属性配置了只允许同一个用户登录系统一次,exceptionIfMaximumExceeded属性配置了在进行第二次登录是是否让第一次登录失效。这里设置为true不允许第二次登录。要让此功能生效,我们还需要在web.xml文件中添加一个监听器,以让Spring Security能获取Session的生命周期事件,配置如下:
<listener>
    <listener-class>
        org.springframework.security.ui.session.HttpSessionEventPublisher
    </listener-class>
</listener>

concurrentSessionController使用sessionRegistry来完成对发布的Session的生命周期事件的处理,org.springframework.security.concurrent.SessionRegistryImpl(实现了 SessionRegistry接口), SessionRegistryImpl类还实现了Spring Framework的事件监听org.springframework.context.Application Listener接口,并实现了该接口定义的onApplicationEvent(ApplicationEvent event)方法用于处理Applic ationEvent类型的事件

<http>
<http auto-config='true'lowercase-comparisons="false"
      access-denied-page="/System/SystemLogin.shtml?error=true" access-decision-manager-ref="accessDecisionManager">
auto-config='true'将自动配置几种常用的权限控制机制
lowercase-comparisons:表示URL比较前先转为小写
access-denied-page:访问拒绝时转向的页面
access-decision-manager-ref:指定了自定义的访问策略管理器。当系统角色名的前缀不是默认的ROLE_时,需要自定义访问策略管理器

<form-login >
<form-login login-page="/System/Login.action" default-target-url="/System/Login!login.action"
       login-processing-url="/System/j_login_check" authentication-failure-url="/System/SystemLogin.action" always-use-default-target="true" />
login-page:指定登录页面(登录表单包含j_username和 j_password输入框)
login-processing-url:指定了客户在登录页面中按下 Sign In按钮时要访问的 URL。与登录页面form的action一致。其默认值为:/j_spring_security_check。
authentication-failure-url:指定了身份验证失败时跳转到的页面
default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面
always-use-default-target:指定了是否在身份验证通过后总是跳转到default-target-url
j_username,输入登陆名的参数名称。
j_password,输入密码的参数名称
_spring_security_remember_me,选择是否允许自动登录的参数名称。

<logout>
<logout logout-success-url="/System/Login!logout.action" invalidate-session="true"
    logout-url="/System/j_spring_security_logout"/>
logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。
logout-success-url:退出系统后转向的URL。
invalidate-session:指定在退出系统时是否要销毁Session。
 
<concurrent-session-control>
<concurrent-session-controlexpired-url="/System/Login.action" max-sessions="1"/>
max-sessions:允许用户帐号登录的次数。范例限制用户只能登录一次。
exception-if-maximum-exceeded:
默认为false,此值表示:用户第二次登录时,前一次的登录信息都被清空。
当exception-if-maximum-exceeded="true"时系统会拒绝第二次登录。
expired-url :session失效后跳转的页面

<authentication-manageralias="authenticationManager" />
    <!--
    <authentication-manageralias="authenticationManager"
         session-controller-ref="concurrentSessionController"/>
    <beans:beanid="sessionRegistry"
         class="org.springframework.security.concurrent.SessionRegistryImpl"/>
    <beans:beanid="concurrentSessionController"
         class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl">
         <beans:propertyname="maximumSessions" value="1" />
         <beans:propertyname="exceptionIfMaximumExceeded" value="false" />
         <beans:propertyname="sessionRegistry" ref="sessionRegistry" />
    </beans:bean>
    -->

<!--访问决策管理器1-->
<b:bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
    <b:property name="allowIfAllAbstainDecisions"value="false"/>
<!--设定是否允许"没人反对就通过"的投票策略 -->
    <b:property name="decisionVoters"><!--投票者 -->
    <b:list>
          <b:beanclass="org.springframework.security.vote.RoleVoter">
          <b:propertyname="rolePrefix" value=""/>
<!--投票者支持的权限前缀,默认是“ROLE_” -->
          </b:bean>
     </b:list>
    </b:property>
</b:bean>

<!--访问决策管理器2-->
<beans:beanid="accessDecisionManager"
         class="org.springframework.security.vote.AffirmativeBased">
         <beans:propertyname="decisionVoters">
             <beans:list>
                 <beans:bean
                      class="org.springframework.security.vote.RoleVoter">
                      <beans:propertyname="rolePrefix" value="ROLE_" />
                 </beans:bean>
             </beans:list>
         </beans:property>
</beans:bean>

 

Spring security提供三种投票通过策略的实现:
1、AffirmativeBased(至少一个投票者同意方可通过)
2、ConsensusBased(多数投票者同意方可通过)
3、UnanimousBased(所有投票者同意方可通过)

<authentication-provider>
DAO身份验证提供者的配置
<authentication-provider user-service-ref="userDetailsService"/>
<beans:beanid="userDetailsService"
         class="com.***.security.UserDetailsServiceImpl">
         <beans:propertyname="UsermCache" ref="UsermCache" />
         <beans:propertyname="UserRoleCache" ref="UserRoleCache"/>
         <beans:propertyname="UserMenuCache" ref="UserMenuCache"/>        
</beans:bean>

 

<!--过滤器安全拦截器,负责授权的filter,检查authentication所授予的权限是否可以访问被访问的资源-->
<beans:beanid="filterSecurityInterceptor"class="com.***.security.RefreshResources">
    <!--覆盖http配置中的intercept-url的配置-->
    <custom-filterbefore="FILTER_SECURITY_INTERCEPTOR" />
    <beans:propertyname="authenticationManager" ref="authenticationManager"/>
    <beans:propertyname="accessDecisionManager" ref="accessDecisionManager"/>
    <beans:propertyname="PermissionService"ref="PermissionService" />
</beans:bean>

private static FilterInvocationDefinitionSource s = null;
private static boolean flag = true; 

/**=============================================get/set=============================================*/
// SystemPermissionService
private SystemPermissionService systemPermissionService;

public SystemPermissionService getSystemPermissionService()
{
return systemPermissionService;
}

public void setSystemPermissionService(
SystemPermissionService systemPermissionService)
{
this.systemPermissionService = systemPermissionService;
}

/**=============================================主方法=============================================*/
@SuppressWarnings("unchecked")
@Override
public ObjectDefinitionSource obtainObjectDefinitionSource()
{
if (s == null)
{
if (flag)
{
try
{
systemPermissionService.cacheInitialization();
}
catch (CacheException e)
{
loger.error(e);
}
}
Map<String, String> resourceMap = systemPermissionService.listResourceMap();
UrlMatcher urlMatcher = null;
LinkedHashMap requestMap = null;
ConfigAttributeEditor editor = null;
if (null != resourceMap && !resourceMap.isEmpty())
{
editor = new ConfigAttributeEditor();
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();
for (Map.Entry<String, String> entry : resourceMap.entrySet())
{
RequestKey key = new RequestKey(entry.getKey(), null);
editor.setAsText(entry.getValue());
requestMap.put(key, (ConfigAttributeDefinition) editor
.getValue());
}
}
if (null != requestMap && !requestMap.isEmpty())
{
urlMatcher = new AntUrlPathMatcher(true);
s = new DefaultFilterInvocationDefinitionSource(urlMatcher,
requestMap);
}
}
return s;
}
public static void refresh()
{
s = null;
flag = false;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值