spring security 菜鸟设定

本人是菜鸟,E文也很烂,偏偏spring security更新很神速,版本之间相差特别大.网上有限的几个教材,也无法拿来就用.硬着头皮,借着spring security 2.x中文使用手册,再结合孙宁振的博文等,经过几天的奋战,终算能跑起来了.下面是根据自已理解,特写的教材.
本人表达能力有限,水平有限,只是由于spring security中文实例资料难找,特凭着脸皮厚,发表本教程,希引出大虾,作出权威的中文教材.是我等菜鸟之福了.

在这里,特别鸣谢spring security 2.x中文手册翻译者,孙宁振网友.

说明:本实例用到了 spring framework 2.5
spring security 2.04
开发工具:netbeans 6.5 cr2中文版.

[b][color=darkblue][size=medium]附件,是本人亲自调试通过的工程.[/size][/color][/b]
需要参考的网友,下载后,可用开发工具,按文件方式打开.能看见所有的源代码,
还有lib.至少netbeans 6.5是这样.
用户名:admin;密码123

菜鸟为了方便菜鸟,把spring security 2.04的下载地址也附上:
http://downloads.sourceforge.net/springframework/spring-security-2.0.4.zip?modtime=1223032765&big_mirror=0

spring官方网站:
www.springsource.org

目录:
1 Dao方式的认证授权原理
1.1 认证授权简略过程:
1.2 Spring security配置思路
2 Dao 形式的认证授权实例
2.1 Web.xml配置
2.2 spring securtity配置
2.2.1 命名空间
2.2.2 默认设定
2.2.3 认证设定
2.2.4 授权设定
2.3 完整的: spring-security.xml
2.4 Login.jsp


=========================[size=medium][color=darkblue][b]正 文[/b][/color][/size]=========================

[color=brown][b][size=medium]
1 Dao方式的认证授权原理[/size][/b][/color]

[color=blue]
1.1 认证授权简略过程:[/color]
[color=blue]
(1) 用户输入用户名,密码[/color][color=blue]
(2) 认证--------Authentication[/color]
根据用户输入信息,查询《用户权限资料表》,得到用户权限名
其中:
《用户权限资料表》的基本形式为:
用户名 密码 权限名1,权限名2,..权限名n
[color=blue]
(3) 授权--------Invocation[/color]
根据权限名,查询《权限明细资料表》,得到具体权限.
其中:
《权限明细资料表》,基本形式为:
网址(或网址加方法) 权限名1, 权限名2,.. 权限名n
从中看出,权限,最终是某个网址可以由哪些角色的用户访问.
[color=blue]
(4) Spring Security根据得到的网址,确定是否允许访问[/color]
[color=blue]
(5) 其他处理(略)[/color]


[b][color=brown][size=medium]
1.2 Spring security配置思路[/size][/color][/b]
揣摩官方的配置思路:
官方设定完整的默认配置。关键环节,允许用户更改默认配置。有一部份默认配置是核心的(如认证与授权),不允许用户替换官方默认配置,但允许用户在这些默认配置的开始或结束后运行用户的配置;有一部份默认配置不是核心的,完全允许用户替代。
在这种假设情况下:
spring security2的这项操作“http标签中,让用户选择官方提供的默认配置”得到解释。
spring security2的这条标签“<custom-filter before="过滤器假名"/>”得到合理解释。同时,认证过滤器与授权过滤器不允许替换默认过滤器也得到解释。


[b][color=brown][size=medium]
2 Dao 形式的认证授权实例[/size][/color][/b]
所谓Dao形式,指认证中所需要的用户权限资料表,权限明细资料表,都放在数据库中,这两个资料表的更新、删除、查询等维护操作由用户编写的dao 完成。这个dao与spring security一起完成用户认证授权工作。这里,为了突出spring security使用方法,这里的dao不与数据库发生联系,仅仅返回spring security所需的数据(数据在dao内中是固定的。),在实际使用中,由用户自行扩展。
[color=blue]
2.1 Web.xml配置[/color]
Spring Security 是用servlet的过滤器实现认证的,因此需要在web.xml中进行配置。格式是固定的。最好位于所有过滤器前面。
代码:---------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是由spring进行配置,还需在web.xml指定spring security的配置文件。
代码:---------------web.xml部份代码.
   
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

说明:
A 指定了spring监听器,启动spring.
B spring securtity的配置文件为: spring-security.xml

[color=blue]
[b][size=medium]2.2 spring securtity配置[/size][/b][/color]
注意:配置文件为spring-security.xml

[color=blue]
2.2.1 命名空间[/color]
核心代码:----- spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="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.1.xsd">

说明:
A ”b:beans”,中的b是命名空间的别名,可由用户自行取名;官方的实例是这样的形式。
B spring-security.xml 中所有的bean的定义,都将前缀”b:bean”.


[color=blue]
2.2.2 默认设定[/color]
所谓默认设定,指spring security 2 已经认定好的了一系列过滤器。省去了早先版本设定一长串过滤器的烦恼。

[color=blue]
(1) 最省事的设定之一[/color]
 
<http auto-config='true'>
<intercept-url pattern="/**" access="ROLE_USER" />
</http>

说明:
A 这里,要求spring security 2 完全按默认处理。通常内存权限设定很管用。
其中:<intercept-url pattern="/**" access="ROLE_USER" />,规定了:名为ROLE_USER的权限,可以访问整个网站。
B 权限名称有规定。至少:前缀“ROLE_”的由大写字母构成的字符串,符合规定。如:ROLE_XXX。

[color=blue]
(2) 最省事的设定之二[/color]

<http>
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login />
<anonymous />
<http-basic />
<logout />
<remember-me />
</http>

说明:
A 这里与前面的方式完全等同。
B form-login 指定了登陆界面。如果没具体指定,spring security将用自身的登陆界面。
C anonymous ,允许匿名访问网站(估计没保护的网页, 匿名者都能访问).
D http-basic 加载系列默认的过滤器。
至少有:AuthenticationProcessingFilter(认证过滤器),
FilterSecurityInterceptor(授权过滤器)
E 凡是这里加载了的过滤器,用户都不能自行设定过滤器替代它们。也就是说AuthenticationProcessingFilter(认证过器) 与FilterSecurityInterceptor(授权过滤器)用户不能替代。
F 凡是这里加载了的过滤器,用户可以自行定义它们中同类的过滤器,挂在相应默认过滤器的前或者后,但是不能替代。
G logout,设定默认的LogoutFilter过滤器。
H remember-me,设定RememberMeProcessingFilter过滤器。
I E与F适用于D、G、H

[color=blue]
(3) 本例中http设定-------- spring-security.xml[/color]


<http>
<intercept-url pattern="/**" access="ROLE_USER"/>
<intercept-url pattern="/login.jsp*" filters="none"/>
<form-login login-page='/login.jsp'/>

<http-basic />
<logout /><!--加载离开过滤器-->
</http>

说明:
A 好像,非得要指定一个内存权限。
B
<intercept-url pattern="/login.jsp*" filters="none"/>
<form-login login-page='/login.jsp'/>

上面这两句,是指定用户自已的登陆界面,是固定形式.前者,表示login.jsp暴露给所有用户,无需保护。如果不要前句,将出现浏览器不允许cookie加载之类的错误提示。

[color=blue]
2.2.3 认证设定[/color]
spring security 2提供了一个专门的认证设定。本节中用户权限,都是指为一个用户设定一个权限名。而这个权限名的定义,不在认证设定处理范围之内,将由授权处理器处理。
[color=blue]
(1) 内存设定用户权限例子[/color]

<authentication-provider>
<user-service>
<user name="张三" password="123" authorities="ROLE_USER,ROLE_DDD" />
</user-service>
</authentication-provider>

说明:这里为张三指定了密码,以及两个权限:“ROLE_USER”与“ROLE_DDD”。

[color=blue]
(2) Dao形式设定用户权限的例子--------- spring-security.xml[/color]

<authentication-provider user-service-ref='userDetailsService'/>
<b:bean id="userDetailsService"
class="fyh.pub.login.security.UserDetailsSerivceImpl">
</b:bean>

其中:fyh.pub.login.security.UserDetailsSerivceImpl是用户自已写的类。这个类实现了spring security 2的UserDetailsService接口。源代码如下:

[color=blue]
(3) UserDetailsService源代码[/color]UserDetailsSerivceImpl.java

package fyh.pub.login.security;

import fyh.pub.login.model.User;
import org.springframework.dao.DataAccessException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;

public class UserDetailsSerivceImpl implements UserDetailsService {
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
UserDetails user=new User();
return user;
}
}

说明:User是用户自已写的类,这个类实现了spring security2的UserDetails接口。

[color=blue]
(4) User源代码[/color]
User.java

package fyh.pub.login.model;
import java.util.ArrayList;
import java.util.List;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

public class User implements UserDetails {
private String id="0";
private String username="admin";
private String password="123";
//省略getter and setter

public GrantedAuthority[] getAuthorities() {
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
list.add(new GrantedAuthorityImpl("ROLE_XXX"));
list.add(new GrantedAuthorityImpl("ROLE_DDD"));
return list.toArray(new GrantedAuthority[list.size()]);
}

public boolean isAccountNonExpired() {return true;}
public boolean isAccountNonLocked() {return true;}
public boolean isCredentialsNonExpired() { return true; }
public boolean isEnabled() {return true; }
}



[color=blue]
2.2.4 授权设定[/color]
这里主要是用了FilterSecurityInterceptor过滤器。

[color=blue]
(1) 引子--------用户自行设定过滤器[/color]
设定格式形如:

<beans:bean id="myFileterName" class="myFileterClass">
<custom-filter position="过滤器假名"/>
</beans:bean>

其中:
A ” position”表示本过滤器,要替代其后的过滤器. "过滤器假名"指示了被替代的过滤器名。
B 除了” position”,还有”before” 与”after”两种方式。分别表示将要把本过滤器挂在其后的过滤器前或后。
例:这里设定了一个abc的过滤器,该过滤器,将挂在http中设定的过滤器-----FilterSecurityInterceptor的前面。

<b:bean id="abc"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<custom-filter before="FILTER_SECURITY_INTERCEPTOR"/>
</b:bean>



[color=blue]
(2) 引子--------标准过滤器假名和顺序[/color]

假名 过滤器类
CHANNEL_FILTER ChannelProcessingFilter
CONCURRENT_SESSION_FILTER ConcurrentSessionFilter
SESSION_CONTEXT_INTEGRATION_FILTER HttpSessionContextIntegrationFilter
LOGOUT_FILTER LogoutFilter
X509_FILTER X509PreAuthenticatedProcessigFilter
PRE_AUTH_FILTER AstractPreAuthenticatedProcessingFilter Subclasses
CAS_PROCESSING_FILTER CasProcessingFilter
AUTHENTICATION_PROCESSING_FILTER AuthenticationProcessingFilter
BASIC_PROCESSING_FILTER BasicProcessingFilter
SERVLET_API_SUPPORT_FILTER SecurityContextHolderAwareRequestFilter
REMEMBER_ME_FILTER RememberMeProcessingFilter
ANONYMOUS_FILTER AnonymousProcessingFilter
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilter
NTLM_FILTER NtlmProcessingFilter
FILTER_SECURITY_INTERCEPTOR FilterSecurityInterceptor
SWITCH_USER_FILTER SwitchUserProcessingFilter


[color=blue]
(3) 定义自已的授权过滤器 [/color]
由于前面, http中已经设定了默认的过滤器。因此,这里自行设定的过滤器将挂在滤认过滤器FilterSecurityInterceptor 的前面。注意:无法替代。
源代码: spring-security.xml
 
<b:bean id="filterSecurityInterceptor11"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<custom-filter before="FILTER_SECURITY_INTERCEPTOR"/>
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="accessDecisionManager" ref="accessDecisionManager" />
<b:property name="objectDefinitionSource"
ref="databaseFilterInvocationDefinitionSource" />
</b:bean>

其中:authenticationManager 是认证管理器。accessDecisionManager是决策管理器。databaseFilterInvocationDefinitionSource是授权管理器(是根据我的理解起的名)。它们随后设定。

[color=blue]
(4) authenticationManager设定[/color]
源代码: spring-security.xml

<b:bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<b:property name="providers">
<b:list>
<b:ref local="daoAuthenticationProvider" />
</b:list>
</b:property>
</b:bean>
<b:bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService" ref="userDetailsService" />
</b:bean>

其中:authenticationManager实例----引用了---->daoAuthenticationProvider实例,
daoAuthenticationProvider实例----引用了----> userDetailsService实例,
而userDetailsService实例在前面的《2.2.3认证设定》(2)中已经设定。

[color=blue]
(5) accessDecisionManager设定[/color]
决策管理器, 经过投票机制来决定是否可以访问某一资源 allowIfAllAbstainDecisions为false时,如果有一个以上的decisionVoters投票通过,则授权通过。 可选的决策机制: ConsensusBased和 UnanimousBased。
源代码: spring-security.xml

<b:bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<b:property name="decisionVoters">
<b:list>
<b:bean class="org.springframework.security.vote.RoleVoter">
<b:property name="rolePrefix" value="" />
</b:bean>
</b:list>
</b:property>
</b:bean>


[color=blue]
(6) databaseFilterInvocationDefinitionSource-----是它获得权限明细资料[/color]
该类,是通过LinkedHashMap对象,传递权限明细资料的。
源代码: spring-security.xml
     class="org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource">
<!-- 匹配url的matcher -->
<b:constructor-arg type="org.springframework.security.util.UrlMatcher"
ref="antUrlPathMatcher" />
<!-- url对应authority的map -->
<b:constructor-arg type="java.util.LinkedHashMap" ref="requestMap" />
</b:bean>

说明:
A antUrlPathMatcher是定义的url格式,随后定义。
B requestMap 装载着权限明细资料。随后定义。

[color=blue]
(7) antUrlPathMatcher[/color]源代码: spring-security.xml

<b:bean id="antUrlPathMatcher"
class="org.springframework.security.util.AntUrlPathMatcher" />


[color=blue]
(8) requestMap------它身上有权限明细资料[/color]
源代码: spring-security.xml

<b:bean id="requestMap"
class="fyh.pub.login.security.RequestMapFactoryBean"
init-method="init">
</b:bean>

说明:RequestMapFactoryBean是由用户自定义的一个类,该类的init方法,返回一个LinkedHashMap对象。随后给出RequestMapFactoryBean的源代码

[color=blue]
(9) RequestMapFactoryBean[/color]
RequestMapFactoryBean.java

package fyh.pub.login.security;

import java.util.LinkedHashMap;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.security.ConfigAttribute;
import org.springframework.security.ConfigAttributeDefinition;
import org.springframework.security.SecurityConfig;
import org.springframework.security.intercept.web.RequestKey;

public class RequestMapFactoryBean implements FactoryBean {
private LinkedHashMap<RequestKey, ConfigAttributeDefinition> requestMap;
public void init() {
requestMap = new LinkedHashMap<RequestKey, ConfigAttributeDefinition>();
RequestKey key = new RequestKey("/**");
ConfigAttribute attribute = new SecurityConfig("ROLE_XXX");
ConfigAttributeDefinition definition = new ConfigAttributeDefinition(
attribute);
requestMap.put(key, definition);

key = new RequestKey("/login.jsp");
attribute = new SecurityConfig("ROLE_EEE");
definition = new ConfigAttributeDefinition(
attribute);
requestMap.put(key, definition);
}

public Object getObject() throws Exception {
if (requestMap == null) {init();}
return requestMap;
}

public Class getObjectType() {return LinkedHashMap.class; }
public boolean isSingleton() {return true;}


}

说明:
A 这里,在类中固定了两个权限。
整个网站可被ROLE_XXX 访问。
/login.jsp 可被ROLE_EEE访问。
B 网址作为 LinkedHashMap的key,权限名放在ConfigAttributeDefinition 中,作为LinkedHashMap的值。

[color=blue]
2.3 完整的spring-seurity.xml[/color]

<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="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.1.xsd">


<http>
<intercept-url pattern="/**" access="ROLE_USER"/>
<intercept-url pattern="/login.jsp*" filters="none"/>
<form-login login-page='/login.jsp'/>
<http-basic />
<logout /><!--加载离开过滤器-->
</http>

<!--设用户权限, 权限表示方式为:用户名 密码 权限名列表.
内存设置方式如下例:
<authentication-provider>
<user-service>
<user name="张三" password="123" authorities="ROLE_USER,ROLE_DDD" />
</user-service>
</authentication-provider>
-->

<!--dao方式设置用户权限-->
<authentication-provider user-service-ref='userDetailsService'/>
<b:bean id="userDetailsService"
class="fyh.pub.login.security.UserDetailsSerivceImpl">
</b:bean>


<!--***********************************************************************
*************************************************************************-->
<!--
负责授权的filter,检查Authentication所授予的权限是否可以访问被访问的资源
-->
<b:bean id="filterSecurityInterceptor11"
class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
<custom-filter before="FILTER_SECURITY_INTERCEPTOR"/>
<b:property name="authenticationManager" ref="authenticationManager" />
<b:property name="accessDecisionManager" ref="accessDecisionManager" />
<b:property name="objectDefinitionSource"
ref="databaseFilterInvocationDefinitionSource" />
</b:bean>

<b:bean id="authenticationManager"
class="org.springframework.security.providers.ProviderManager">
<b:property name="providers">
<b:list>
<b:ref local="daoAuthenticationProvider" />
</b:list>
</b:property>
</b:bean>
<b:bean id="daoAuthenticationProvider"
class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
<b:property name="userDetailsService" ref="userDetailsService" />
</b:bean>

<b:bean id="accessDecisionManager"
class="org.springframework.security.vote.AffirmativeBased">
<b:property name="decisionVoters">
<b:list>
<b:bean class="org.springframework.security.vote.RoleVoter">
<b:property name="rolePrefix" value="" />
</b:bean>
</b:list>
</b:property>
</b:bean>

<b:bean id="databaseFilterInvocationDefinitionSource"
class="org.springframework.security.intercept.web.DefaultFilterInvocationDefinitionSource">
<b:constructor-arg type="org.springframework.security.util.UrlMatcher"
ref="antUrlPathMatcher" />
<!-- url对应authority的map -->
<b:constructor-arg type="java.util.LinkedHashMap" ref="requestMap" />
</b:bean>

<b:bean id="antUrlPathMatcher"
class="org.springframework.security.util.AntUrlPathMatcher" />

<b:bean id="requestMap"
class="fyh.pub.login.security.RequestMapFactoryBean"
init-method="init">
</b:bean>

</b:beans>




[color=blue]
2.4 Login.jsp[/color]说明: 如果用户,要用自已的登陆界面,需要
(1) 把form的action设成j_spring_security_check
(2) 用户名设成j_username
(3) 密码名设成j_password
以上三点,是spring security的约定。

login.jsp核心代码

<form action="j_spring_security_check" method="post">
<table>
<tr>
<td><label for="username">用户名:</label></td>
<td><input type="text" id="username" name="j_username"
value="${SPRING_SECURITY_LAST_USERNAME}"/></td>
</tr>
<tr>
<td><label for="password">密码:</label></td>
<td><input type="password" id="password" name="j_password" value=""/></td>
</tr>
<tr><td></td>
<td><input type="checkbox" name="_spring_security_remember_me">两周内记住我</td>
</tr>
<tr><td colspan="2"><input type="submit" value="提交"/>
<input type="reset" value="重置"/></td></tr>
</table>
</form>



============================================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值