Spring专题

Spring security深入使用(2)

上页

通过ACL的授权

  通过‹http›的‹intercept-url›进行配置:

<sec:http access-decision-manager-ref="accessDecisionManager">
  <sec:intercept-url pattern="/app/messageList*" access="ROLE_USER,ROLE_ANONYMOUS"/>
  <sec:intercept-url pattern="/app/messagePost*" access="ROLE_USER"/>
  <sec:intercept-url pattern="/app/messageDelete*" access="ROLE_ADMIN"/>
  <sec:intercept-url pattern="/app/*" access="ROLE_USER"/>

  <form-login login-page="/login.jsp" default-target-url="/app/messagePost"
    authentication-failure-url="/login.jsp?error=true"/>
  <!-- Other settings -->
</sec:http>

  每个 intercept-url 规定了一个 url模式和角色,具有这个角色的用户可以访问这些URL。注意url-pattern总是以 ‘*’结束,如果 ‘*’ 没有规定,提供黑客在url中提供一些参数绕过安全机制。

Spring将这些URL拦截到FilterSecurityInterceptor. 下面是没有使用‹intercept-url›:另外一种类似配置。

<sec:custom-filter position="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor" />
<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
  <property name="authenticationManager" ref="authenticationManager"/>
  <property name="accessDecisionManager" ref="accessDecisionManager"/>
  <property name="securityMetadataSource">
  <sec:filter-security-metadata-source lowercase-comparisons="true" request-matcher="ant" use-expressions="true">
    <sec:intercept-url pattern="/app/messageList*" access="ROLE_USER,ROLE_ANONYMOUS"/>
    <sec:intercept-url pattern="/app/messagePost*" access="ROLE_USER"/>
    <sec:intercept-url pattern="/app/messageDelete*" access="ROLE_ADMIN"/>
    <sec:intercept-url pattern="/app/*" access="ROLE_USER"/>
  </sec:filter-security-metadata-source>
  </property>
</bean>

从上面的代码可以看出,匿名用户只能访问messageList的页面,其他页面必须登录。

如果你仔细观察的bean声明,有一个属性'的AccessDecisionManager “ 。这样做的目的是什么?

这个bean这实际上实现访问控制决策。它有实现AccessDecisionManager接口。 Spring提供了三个内置的访问决策管理。

  在了解访问决策管理器是如何工作之前,我们需要知道AccessDecisionVoter是什么。AccessDecisionManager实际上是由一个或多个决定是否访问的投票者的组合体。这个组合封装了允许/拒绝/放弃观看资源的用户逻辑。投票者决定结果是通过ACCESS_GRANTED , ACCESS_DENIED和ACCESS_ABSTAIN中的AccessDecisionVoter接口中定义的常量字段来表示。我们可以定义自定义访问决策,并注入到我们的访问决策管理器中。

看看内置决策管理者:

AffirmativeBased :至少一个投票者必须决定授予访问权限
ConsensusBased :多数投票者必须授予访问权限
UnanimousBased :所有投票者都必须投票或放弃投票授予访问权限(无投票表决拒绝访问)

默认情况下, AffirmativeBased访问决策管理器将由两个投票者初始化:RoleVoter和AuthenticatedVoter 。

如果用户具有访问资源的角色,RoleVoter授权访问,角色必须有“ ROLE_ ”前缀,下面我们看到也可以定制其他前缀。

AuthenticatedVoter是在用户被验证是授权访问,接受的身份验证级别有:IS_AUTHENTICATED_FULLY , IS_AUTHENTICATED_REMEMBERED和IS_AUTHENTICATED_ANONYMOUSLY

下面展示假设我们要定义一个自定义的投票者,并把它添加到访问决策管理器:

<sec:http access-decision-manager-ref="accessDecisionManager" auto-config="true">
  <!-- filters declaration go here-->
</sec:http>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
  <property name="decisionVoters">
    <list>
      <bean class="org.springframework.security.access.vote.RoleVoter">
       <!-- Customize the prefix-->
       <property name="rolePrefix" value="ROLE_"/>
      </bean>
      <bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>
      <bean class="com.pramati.security.voters.CustomVoter"/>
    </list>
  </property>
</bean>

登录退出

  登录退出配置如下:

<sec:http>

  <!-- Other filter declarations here -->

  <sec:logout />

</sec:http>

缺省登出页面的URL是/j_spring_security_logout,可以规定 logout-url attribute.优化这个URL.

退出成功后,缺省是根路径,通过下面可以指定退出成功后的URL:

<sec:logout logout-url="/j_logMeOut" logout-success-url="/app/messageList"/>

如果你想在登陆页面不是默认的,而是一个特定的在不同的场景不同URL,那么我们必须实现LogoutSuccessHandler并提供了一个参考<logout>元素

<sec:logout logout-url="/j_logMeOut" success-handler-ref="customLogoutSuccessHandler"/>

然后定义Bean:

<sec:custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
  <constructor-arg value="/pages/Security/logout.html" />
    <constructor-arg>
      <list>
        <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
      </list>
    </constructor-arg>
  <property name="filterProcessesUrl" value="/j_logMeOut"/>
</bean>

匿名登录

  缺省Spring创建anonymous角色。当你规定角色是ROLE_ANONYMOUS’ 或‘IS_AUTHENTICATED_ANONYMOUSLY’, 任何人都可以访问资源。

在AffirmativedBased 访问控制器中,RoleVoter看到‘ROLE_ANONYMOUS’设置就授权访问,类似AuthenticatedVoter 看到‘IS_AUTHENTICATED_ANONYMOUSLY’.授权访问。

假设你要分配给匿名用户不同的角色名,则可以覆盖默认的配置如下:

<sec:http>
  <sec:intercept-url pattern="/login.jsp*" filters="none"/>
  <sec:intercept-url pattern="/*" access="ROLE_USER"/>

  <!-- Defines a custom role in place of ROLE_ANONYMOUS.
  ROLE_ANONYMOUS will no more work, use ROLE_GUEST instead of it-->
  <sec:anonymous username="guest" granted-authority="ROLE_GUEST" />
</sec:http>

<p style="text-align: justify;">Here is the how the underlying filter can be defined if you don't want to use ?anonymous? element:</p>

1
<sec:custom-filter position="ANONYMOUS_FILTER" ref="anonymousFilter" />
<bean id="anonymousFilter" class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter" >
    <property name="userAttribute" value="ROLE_GUEST" />
</bean>

下页

.基于容器的用户安全认证授权系统

权限专题

spring security安全登陆源码下载