javascript
Spring mvc 3.0 入门及应用
【一】Spring應用
?
Spring?支持json格式的jar
?
jackson-all-1.7.3??http://jackson.codehaus.org/
?
?
?
Spring MVC 3.x annotated controller的幾點心得體會
?
(最優化使用http://www.javaeye.com/topic/828513)
?
一、callback回調
?
template method(模板方法設計模式)-hibernateTemplate
?
?
?
二、JPA2.0的配置
?
src/META-INF/persistence.xml
?
?
?
webContent/META-INF/context.xml
?
?
?
webContent/WEB-INF/applicationContext.xml
?
?
?
?
?
三、Hibernate配置
?
【二】spring3.0.5與hibernate3.6.1(JPA2.0)整合
?
?
?
【三】springMVC使用
?
?
?
?
?
?
?
Spring MVC核心??流程示意圖
?
Dispatcher Servlet??--front controller前端總控制器
?
?
?
Controller???--應用開發的控制器,實現controller接口,
?
?
?
Handler Mapping??--控制器的映射,控制controller策略
?
?
?
ViewResolver??& View --視圖策略,View是試圖預處理
?
?????????????InternalResourceViewResolver --jsp和jstl的解析器,
?
?
?
?
?
?
?
Interceptors?:攔截器
?
?
?
LocalResolver?:國際化
?
?
?
Validate?:驗證
?
?
?
?
?
ClassNameHandlerMapping?類名控制器--按類名匹配的abc.test的AbcController
?
BeanNameUrlHandlerMapping <bean name="/to_add.test" class=""/>
?
?
?
?
?
?
?
?
?
?
?
--------------------------------基于注解的MVC
?
基于注解的SpringMVC
?
?
?
一、@Controller??-類上
?
?
?
@RequestMapping --修飾兩種類型:方法上?和?類上
?
??(1)類級別上:表示首先定義了相對的父路徑,那么在方法上定義的路徑是相對于類級別上的。
?
??(2)方法上:如果類級別沒有RequestMapping映射,則相對于應用,如果類級別有,則是相對于
?
類級別的注解的路徑
?
?
?
?
?
二、路徑變量:restful風格?--PathVariable
?
?
?
http://localhost:8080/@mvc/test/start/zhangsan.do --請求的參數作為url的一部分來存在
?
?
?
http://localhost:8080/@mvc/test/start/lisi.do
?
?
?
@RequestMapping("/start/{name}/{age}")
?
public String start(@PathVariable("name")?String name,@PathVariable("age") int
?
nianling){ //此處name與上面的name一致,
?
?
?
}
?
//此處注意:java編輯的debug模式?和release模式
?
?
?
?
?
三、根據不同的請求方法(POST/GET),映射到不同的處理方法
?
?
?
@RequestMapping(value="/start",method=RequestMethod.GET)
?
public String PostStart(){ /
?
?
?
}
?
?
?
@RequestMapping(value="/start",method=RequestMethod.POST)
?
public String start(){ /
?
?
?
}
?
?
?
四、數據綁定,注解中的實現
?
?
?
@RequestMapping(value="/{test}",method=RequestMethod.GET)
?
public String start(){ /
?
?
?
}
?
?
?
@Initbinder??--初始化綁定器標注
?
public void initbinder(WebRequestDataBinder binder,HttpServletRequest request){
?
?
?
??binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat
?
("yyyy-MM-dd"),false));
?
?
?
}
?
?
?
五、處理請求的方法,接收的參數和返回的參數
?
?
?
1.接收的參數:數量與順序沒有要求
?
=
?
(1)沒有參數()
?
(2)(@Pathvariable anyType)
?
(3)(request,response,session,)
?
?//session的前提,當前請求session可用。
?
(4)request參數@RequestParam??anyType //--?id=45參數,通過類型轉換器轉換
?
(5)@CookieValue anyType??CookieName???//cookie值取出,通過類型轉換
?
(6)@RequestHeader("user-Agent") AnyType abc???--從請求的頭部中取出正確的值,例如(user-
?
Agent,content etc)
?
(7)經常調用out = response.getWriter()
?
@RequestMapping
?
public void??testAllArguments(PrintWriter out){
?
//out = response.getWriter();
?
- out.println();
?
}
?
?
?
(8)??可以是Map
?
public ModelAndView test(Map model){
?
?????????//返回modelandview
?
?model.put("","");
?
?return new ModelAndView("viewName");??
?
}
?
?
?
(9)表單參數生成bean?注入
?
public String test(User user,BindingResult result)
?
//user自動為command對象,直接注入,此處要進行數據綁定的處理(進行綁定器)
?
//BindingResult --??處理錯誤綁定信息,判斷是否綁定錯誤信息,進行處理,與數據驗證有關
?
?
?
2.返回值類型
?
(1)void -直接輸出結果,兩種情況:
?
第一:有out對象輸出:out.print
?
第二:沒有out輸出的話,會生成一個隱含的viewName-->按請求路徑解析出的
?
${appname}/test/xxx.do -->/WEB-INF/page/test/xxx.jsp
?
?
?
(2)String?類型:viewName
?
(3)任意類型AnyType對象?--//model("user",user) ,user自動填充到模型中。試圖名為默認解析
?
的名字
?
?
?
public User testUser(){
?
?
?
}
?
(4)返回list --//model.("userList",list)
?
public List<User> queryUsers(){
?
?????????return null;
?
}
?
(5)Model,Map,ModelAndView?只返回模型是,試圖名按默認解析
?
?
?
六、重定向視圖?return "redirect:/usr_list"
?
?
?
@Controller
?
@RequestMammping("/user")
?
publc class UserController{
?
????????
?
?????????@RequestMapping(method=RequestMethod.GET)
?
public String addForm(){
?
?????????return "add_user";
?
}
?
@RequestMapping(method=RequestMethod.POST)
?
public String addUser(User user){
?
?
?
?????????return "redirect:/user_list"; //重定向視圖,防止再次進行提交操作,重復提交
?
}
?
}
?
產生原因:request.forward();-帶著參數,由服務器轉到另外一個方法
?
response.sendRedirect(b) --重定向方法,不帶參數轉換,瀏覽器知道發生了改變,瀏覽器?再次
?
發生一次請求b
?
解決方法:將結果重定向到?另一個頁面:return "redirect:success";
?
?
?
七、ExcelView??JsperReport,Pdf,XML視圖
?
?
?
八、攔截器,視圖的國際化,表單驗證
?
?
?
1.攔截器:全局日志,權限管理(攔截器細粒度)
?
?
?
(1)定義一個攔截器,多個攔截器形成鏈:實現HanderInerceptor接口,三個方法
?
?
?
preHandler()
?
postHandler()
?
afterCompletion()
?
(2)配置攔截器:
?
<mvc:interceptors>
?
?????????<mvc:interceptor>
?
???????????????????<mvc:mapping path="/usr/*"/> --可選
?
???????????????????<bean class="test.web.myInerceptor"/>
?
?????????</mvc:interceptor>
?
</mvc:interceptors>
?
?
?
2.國際化(視圖)--中文/英文/日文/韓文
?
?
?
引入spring標簽庫:
?
<%@ tablib??uri="http://www.springframework.org/tags" prefix="spring" %>
?
?
?
<div>
?
?????????<spring:message code="welcome"/> --引用屬性文件的welcome
?
</div>
?
配置資源文件
?
<bean id="resourceMessage(此名不可變)"
?
class="org.sf.context.support.resourceBundleMessageSource">
?
?????????<property name="basename" value="mess"/>
?
?????????<property name="basenames">
?
???????????????????<value>...</value>
?
???????????????????<value>...</value>
?
?????????</property>
?
</bean>
?
?
?
3.驗證Validate(Spring后端驗證采用JSR-303 validate bean標準,前斷用javascript)
?
后端用@Valid注解?--自動調用約束條件驗證,條件在實體類中指定
?
?
?
比較的好的實現:hibernate - validator 4.0?
?
?
?
class User
?
{
?
@NotEmpty
?
private string name
?
@Size(max=20,min=6)
?
private String password;
?
?
?
}
?
?
?
public String addUser(@Valid User user,BindingResult result){
?
?
?
}
?
九、對json的原生支持
?
spring mvc ajax?使用json
?
http://liyixing1.iteye.com/blog/1098743
?
【四】spring與spring3.0.5_quartz1.8.4整合
?
(e:\openprojects\spring)
?
http://www.javaeye.com/topic/906313?關于調度的框架
?
?
?
【五】spring3.0.5與zk5.0.5的集成詳細說明
?
http://www.javaeye.com/topic/891134
?
?
?
?
?
?
?
?
?
?
?
【六】SpringSecurity配置
?
重要參考文獻:http://sarin.javaeye.com/blog/829738
?
準備jia文件
?
一、??????基礎配置
?
1.配置過濾器
?
?
?
1.??<context-param>??
2.??????????<param-value>??
3.??????????/WEB-INF/board-service.xml??
4.??????????/WEB-INF/board-security.xml??
5.??????????</param-value>??
6.??????</context-param>??
1.??<filter>??
2.??????????<filter-name>springSecurityFilterChain</filter-name>??
3.??????<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>??
4.??????</filter>??
5.??????<filter-mapping>??
6.??????????<filter-name>springSecurityFilterChain</filter-name>??
7.??????????<url-pattern>/*</url-pattern>??
8.??????</filter-mapping>?
?
?
?
過濾器配置:初始化參數和?springscurity過濾器
?
?
?
2.SpringMVC?的sevlet配置
?
?
?
1.??<?xml?version="1.0"?encoding="UTF-8"?>??
2.??<beans?xmlns="http://www.springframework.org/schema/beans"??
3.??????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
4.??????xmlns:security="http://www.springframework.org/schema/security"??
5.??????xmlns:context="http://www.springframework.org/schema/context"??
6.??????xsi:schemaLocation="http://www.springframework.org/schema/beans??
7.??http://www.springframework.org/schema/beans/spring-beans-3.0.xsd??
8.??http://www.springframework.org/schema/context??
9.??http://www.springframework.org/schema/context/spring-context-3.0.xsd??
10.?http://www.springframework.org/schema/security??
11.?http://www.springframework.org/schema/security/spring-security-3.0.xsd">??
12.?????<context:component-scan?base-package="org.ourpioneer.board.web"?/>??
13.?????<bean??
14.?????class="org.springframework.web.servlet.view.InternalResourceViewResolver">??
15.?????????<property?name="prefix"?value="/WEB-INF/jsp/"?/>??
16.?????????<property?name="suffix"?value=".jsp"?/>??
17.?????</bean>??
18.?????<security:global-method-security??
19.?????????jsr250-annotations="enabled"?secured-annotations="enabled"?/>??
20.?</beans>??
?
?
?
以上配置springsecurity配置為支持注釋形式。Spring security配置的文件,必須在springmvc初始化的配置文件中初始化,否則不起作用。也就是說secrrity的配置文件必須和spring mvc的配置文件?都被spring MVC放在一起(web.xml配置springmvc時,init-para也要把security的放進去)框架加載。
?
?
?
3.配置自定義登錄界面
?
1.??<security:http??access-denied-page="/accessDenied.jsp"?>??
2.??????<security:form-login?login-page="/login.jsp"??
3.??login-processing-url="/login"?default-target-url="/messageList.htm"??
4.??????????????authentication-failure-url="/login.jsp?error=true"?/>??
5.??????<security:logout?logout-success-url="/login.jsp"?/>??
6.??</security:http>??
?
?
?
(1)login-page屬性配置的是登錄頁面;access-denied-page:自定義訪問拒絕(無權訪問)頁面。
?
(2)login-processing-url就是我們處理登錄邏輯的請求地址,默認的是j_spring_security_check;
?
(3)default_target_url就是默認的登錄成功轉向的目標地址,這里是消息列表頁面。
?
(4)authentication-failure-url,驗證失敗轉向的頁面,這里我們附加一個參數error,頁面里面也有體現,就是用它來控制失敗信息的打印的。
?
(5)logout-success-url就是退出后轉向的頁面,這里是到登錄頁面,沒錯,退出后回到登錄頁面。
?
二、從數據庫中讀取用戶信息
?
三種方式:標準數據表方式??、自定義數據表方式?和?屬性文件properties方式
?
1.標準數據表
?
(1)???????數據表:
?
(2)????CREATE?TABLE?`users`?(??
(3)??????`USERNAME`?varchar(10)?NOT?NULL,??
(4)??????`PASSWORD`?varchar(32)?NOT?NULL,??
(5)??????`ENABLED`?tinyint(1)?NOT?NULL,??
(6)??????PRIMARY?KEY?(`USERNAME`)??
(7)????)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8??
(8)??????
(9)????CREATE?TABLE?`authorities`?(??
(10)????`USERNAME`?varchar(10)?NOT?NULL,??
(11)????`AUTHORITY`?varchar(10)?NOT?NULL,??
(12)????KEY?`FK_USERNAME_AUTHORITY`?(`USERNAME`),??
(13)????CONSTRAINT?`FK_USERNAME_AUTHORITY`?FOREIGN?KEY?(`USERNAME`)?REFERENCES?`users`?(`USERNAME`)?ON?DELETE?NO?ACTION?ON?UPDATE?NO?ACTION??
(14)??)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8?
?
?
?
用戶與角色是一對多的關系,一個用戶可以設置多個角色
?
?
?
?
?
?
?
(2)配置方式?–認證管理器配置方式
?
1.??<security:authentication-manager>??
2.??????<security:authentication-provider>??
3.??????????<security:password-encoder?ref="md5Encoder"?/>??
4.??????????<security:jdbc-user-service?data-source-ref="dataSource"?/>??
5.??????</security:authentication-provider>??
6.??</security:authentication-manager>?
?
這里有自定義的MD5加密器
?
<bean?id="md5Encoder"?class="org.ourpioneer.board.util.MD5Encoder"?/>?
?
2.自定義數據表:
?
(1)???????數據表
?
(2)????CREATE?TABLE?`b_user`?(??
(3)??????`ID`?int(11)?NOT?NULL?AUTO_INCREMENT,??
(4)??????`USERNAME`?varchar(20)?NOT?NULL,??
(5)??????`PASSWORD`?varchar(32)?NOT?NULL,??
(6)??????PRIMARY?KEY?(`ID`)??
(7)????)?ENGINE=InnoDB?AUTO_INCREMENT=4?DEFAULT?CHARSET=utf8??
(8)????CREATE?TABLE?`b_userrole`?(??
(9)??????`ID`?int(11)?NOT?NULL,??
(10)????`USERID`?int(11)?NOT?NULL,??
(11)????`ROLE`?varchar(15)?NOT?NULL,??
(12)????PRIMARY?KEY?(`ID`),??
(13)????KEY?`FK_USERID_USERROLE`?(`USERID`),??
(14)????CONSTRAINT?`FK_USERID_USERROLE`?FOREIGN?KEY?(`USERID`)?REFERENCES?`b_user`?(`ID`)?ON?DELETE?NO?ACTION?ON?UPDATE?NO?ACTION??
(15)??)?ENGINE=InnoDB?DEFAULT?CHARSET=utf8?
?
?
?
(2)配置方式:
?
由于表名,字段名和結構都和Security框架默認的不匹配,只好通過SQL語句來讓Security框架識別了:
?
1.??<security:authentication-manager>??
2.??????<security:authentication-provider>??
3.??????????<security:password-encoder?ref="md5Encoder"?/>??
4.??????????<security:jdbc-user-service??
5.??????????????data-source-ref="dataSource"??
6.??????????????users-by-username-query="select?USERNAME,PASSWORD,'true'?as?ENABLED?from?b_user?where?USERNAME=?"??
7.??????????????authorities-by-username-query="select?u.USERNAME,ur.ROLE?as?AUTHORITIES?from?b_user?u,b_userrole?ur?where?u.USERNAME=??and?u.ID=ur.USERID"?/>??
8.??????</security:authentication-provider>??
9.??</security:authentication-manager>??
?
?
?
注:user實際上是單個字段,用戶名username,密碼password,用戶是否禁用(true/false)。此處true/false沒有從數據庫中提取,直接寫為ENABLE,(DISABLE表示false)。
?
3.基于proptetis屬性文件的配置方式
?
(1)屬性文件格式:/WEB-INF/user.properties
?
1.??admin=123,ROLE_ADMIN,ROLE_USER??
2.??user1=123,ROLE_USER??
3.??user2=123,enabled,ROLE_USER??
?
這里面名/值對的形式排列的,值的字段比較多。admin/user1是用戶名,不用多說,等號后面第一位是密碼,這里沒有加密。第二位是是否禁用狀態,這是可選的,默認是enabled,第三位以后就是用戶所擁有的角色了,這么使用和前面的效果也是相同的。
?
?
?
(2)配置方式—驗證器
?
1.??<security:authentication-manager>??
2.??????<security:authentication-provider>??
3.??????????<security:user-service?properties="/WEB-INF/users.properties"/>??
4.??????</security:authentication-provider>??
5.??</security:authentication-manager>?
?
三、訪問控制
?
訪問控制是Security框架的另一大特性,可以對其進行自定義的擴展,設計符合我們業務邏輯的控制。這比URL攔截又深入了一步,可以過濾的東西又多了。
?
設計到訪問控制,要引入一個概念,誰來決定能否訪問,從而進行控制。Security框架中的訪問控制管理有三種方案:至少有一個同意訪問,全部同意訪問,全部棄權或都同意訪問(也就是沒有拒絕的)。如何同意?投票產生!Security框架一個可配置的元素就出來了,那就是投票器了。和現實的投票一樣,分同意,反對和棄權三類。
?
下面我們應用第一類訪問控制管理:至少有一個投票器同意訪問,在配置文件中這么來設置:
?
1.??<bean?id="accessDecisionManager"??
2.??????class="org.springframework.security.access.vote.AffirmativeBased">??
3.??????<property?name="decisionVoters">??
4.??????????<list>??
5.??????????????<bean?class="org.springframework.security.access.vote.RoleVoter"?/>??
6.??????????????<bean?class="org.springframework.security.access.vote.AuthenticatedVoter"?/>??
7.??????????</list>??
8.??????</property>??
9.??</bean>??
?
?
?
先看看對控制器方法的安全訪問,這個配置相對簡單,在配置文件中,把安全配置文件和controller的聲明放在一起:?
?
1.??<context:component-scan?base-package="org.ourpioneer.board.web"?/>??
2.??<security:global-method-security??
3.??????????jsr250-annotations="enabled"?secured-annotations="enabled"?/>??
?
?
?
?
?
?
?
?
?
四、SpringSecurity與CAS集成
?
http://www.family168.com/tutorial/springsecurity3/html/cas.html
?
示例文件:下載
?
http://www.jarvana.com/jarvana/browse/org/springframework/security/
?
1.所需jar文件
?
Cas Client的jar包:
?
cas-client-core-3.1.10.jar
?
SpringSecurity的jar文件
?
spring-security-cas-client-3.0.5.RELEASE.jar
?
spring-security-config-3.0.5.RELEASE.jar
?
spring-security-core-3.0.5.RELEASE.jar
?
spring-security-web-3.0.5.RELEASE.jar
?
?
?
2.配置文件
?
(1)配置userService?讀取本地應用程序的角色權限信息
?
A.基于xml方式配置
?
?user-service?用戶的信息配置,本應用程序自身要有一個用戶列表,單點登錄結束后需要從本地應用中讀取角色信息?下面是基于xml的配置方式,實際應用中應該使用數據庫方式
?
????<security:user-service id="userService">
????<security:user name="lgj" password="sailor" authorities="ROLE_SUPERVISOR,ROLE_USER" />
????????<security:user name="rod" password="rod" authorities="ROLE_SUPERVISOR,ROLE_USER" />
????????<security:user name="dianne" password="dianne" authorities="ROLE_USER" />
????????<security:user name="scott" password="scott" authorities="ROLE_USER" />
????</security:user-service>
?
B.基于數據庫方式配置
?
?
?
????????<security:jdbc-user-service??id="userService"
????????????data-source-ref="dataSource"?
????????????users-by-username-query="select USERNAME,PASSWORD,'true' as ENABLED from b_user where USERNAME=?"?
????????????authorities-by-username-query="select u.USERNAME,ur.ROLE as AUTHORITIES from b_user u,b_userrole ur where u.USERNAME=? and u.ID=ur.USERID"?/>?
?
???
?
(2)完整xml文件
?
?
?
<?xml?version="1.0"?encoding="UTF-8"?>
?
<beans?xmlns="http://www.springframework.org/schema/beans"
????xmlns:security="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.0.xsd
????????????????????????http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
????<!--?配置controller采用注解方式?-->
????<security:global-method-security
???????jsr250-annotations="enabled"?secured-annotations="enabled"
???????access-decision-manager-ref="accessDecisionManager"?/>
????<!—配置退出url,攔截器等信息,由于上方使用了注解方式,因此攔截器可省略?-->
????<security:http?entry-point-ref="casProcessingFilterEntryPoint">
????????<security:logout?logout-success-url="/cas-logout.jsp"/>
????????<security:custom-filter?ref="casAuthenticationFilter"?after="CAS_FILTER"/>
????</security:http>
?
????<security:authentication-manager?alias="authenticationManager">
????????<security:authentication-provider?ref="casAuthenticationProvider"/>
????</security:authentication-manager>
?
????<bean?id="casAuthenticationFilter"?class="org.springframework.security.cas.web.CasAuthenticationFilter">
????????<property?name="authenticationManager"?ref="authenticationManager"/>
????????<property?name="authenticationFailureHandler">
????????????<bean?class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
????????????????<property?name="defaultFailureUrl"?value="/casfailed.jsp"/>
????????????</bean>
????????</property>
????????<property?name="authenticationSuccessHandler">
????????????<bean?class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
????????????????<property?name="defaultTargetUrl"?value="/"/>
????????????</bean>
????????</property>
????????<property?name="proxyGrantingTicketStorage"?ref="proxyGrantingTicketStorage"?/>
????????<property?name="proxyReceptorUrl"?value="/secure/receptor"?/>
????</bean>
?
<bean?id="casProcessingFilterEntryPoint"?class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">
<!--?配置單點登錄的地址?-->
????????<property?name="loginUrl"?value="https://sso.qau.edu.cn/cas/login"/>
????????<property?name="serviceProperties"?ref="serviceProperties"/>
????</bean>
?
????<bean?id="casAuthenticationProvider"?class="org.springframework.security.cas.authentication.CasAuthenticationProvider">
????????<property?name="userDetailsService"?ref="userService"/>
????????<property?name="serviceProperties"?ref="serviceProperties"?/>
????????<property?name="ticketValidator">
????????????<bean?class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">
????????????????<constructor-arg?index="0"?value="https://sso.qau.edu.cn/cas"?/>
????????????????<property?name="proxyGrantingTicketStorage"?ref="proxyGrantingTicketStorage"?/>
<!--?配置本地應用的地址?-->
????????????????<property?name="proxyCallbackUrl"?value="http://210.44.48.15:8080/SpringMVCSpringJPA2CAS/secure/receptor"?/>
????????????</bean>
????????</property>
????????<property?name="key"?value="an_id_for_this_auth_provider_only"/>
????</bean>
?
????<bean?id="proxyGrantingTicketStorage"?class="org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl"?/>
?
????<bean?id="serviceProperties"?class="org.springframework.security.cas.ServiceProperties">
????????<property?name="service"?value="http://210.44.48.15:8080/SpringMVCSpringJPA2CAS/j_spring_cas_security_check"/>
????????<property?name="sendRenew"?value="false"/>
????</bean>
<!-- user-service?用戶的信息配置,本應用程序自身要有一個用戶列表,單點登錄結束后需要從本地應用中讀取角色信息
下面是基于xml的配置方式,實際應用中應該使用數據庫方式
????<security:user-service id="userService">
????<security:user name="lgj" password="sailor" authorities="ROLE_SUPERVISOR,ROLE_USER" />
????????<security:user name="rod" password="rod" authorities="ROLE_SUPERVISOR,ROLE_USER" />
????????<security:user name="dianne" password="dianne" authorities="ROLE_USER" />
????????<security:user name="scott" password="scott" authorities="ROLE_USER" />
????</security:user-service> -->
???
????????<security:jdbc-user-service??id="userService"
????????????data-source-ref="dataSource"?
????????????users-by-username-query="select USERNAME,PASSWORD,'true' as ENABLED from b_user where USERNAME=?"?
????????????authorities-by-username-query="select u.USERNAME,ur.ROLE as AUTHORITIES from b_user u,b_userrole ur where u.USERNAME=? and u.ID=ur.USERID"?/>?
???
????<!--?訪問控制,可以進行自定義的擴展?-->
????<bean?id="accessDecisionManager"
???????class="org.springframework.security.access.vote.AffirmativeBased">
???????<property?name="decisionVoters">
???????????<list>
??????????????<bean?class="org.springframework.security.access.vote.RoleVoter"?/>
??????????????<bean?class="org.springframework.security.access.vote.AuthenticatedVoter"?/>
??????????????<bean?class="cn.edu.qau.acl.IPAddressVoter"?/>
???????????</list>
???????</property>
????</bean>
</beans>
?
?
?
?
?
?
?
?
?
(3)web.xml配置退出系統的過濾器和偵聽器
?
?
?
<!--?單點登出過濾器,應放到最上方?-->
????<filter>
???????<filter-name>CAS Single Sign Out Filter</filter-name>
???????<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>
<filter-mapping>
???????<filter-name>CAS Single Sign Out Filter</filter-name>
???????<url-pattern>/*</url-pattern>
????</filter-mapping>
?
?
<listener>
????????<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
????</listener>
?
?
?
?
(4)配置單點登錄服務器的應用管理
?
?
?
3.訪問方法
?
(1)獲取principal對象
?
?
?
<p>Your principal object is....:?<%=?request.getUserPrincipal()?%></p>
?
(2)顯示用戶名
?
?
?
???????????Welcome!
?
???????????<security:authentication?property="name"?/> --顯示用戶名
?
???????</h2>
?
???????角色:<security:authentication?property="authorities"?var="authorities"?/>
?
???????<ul>
?
???????????<c:forEach?items="${authorities}"?var="authority">
?
??????????????<li>
?
??????????????????${authority.authority}
?
??????????????</li>
?
???????????</c:forEach>
?
???????</ul>
?
??????
?
或者:
?
<%
?
if?(request.getRemoteUser() !=?null) {
?
????out.println("<div class=\"authenticated\">");
?
????out.println("User: "?+ request.getRemoteUser());
?
????//Logout not yet implemented!
?
????//out.println(" ");
?
????//out.println("<a href=\"#\">LOGOUT</a>");
?
????out.println("</div>");
?
}?else?{
?
????out.println("Not logged in.");
?
}
?
%>
?
(3)角色判斷
?
<%if?(request.isUserInRole("ROLE_SUPERVISOR")) {?%>
?
????You are a supervisor! You can therefore see the?<a?href="extreme/index.jsp">extremely secure page</a>.<br><br>
?
<%?}?%>
?
(4)顯示錯誤信息
?
<font?color="red">
?
????Your CAS?credentials?were rejected.<br/><br/>
?
????Reason:?<%=?((AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY)).getMessage()?%>
?
</font>
?
(5)退出登錄
?
退出session登錄,此時還沒有注銷cas,重新刷新頁面還可以拿到cas認證信息,并且登錄成功:
?
<a?href="<c:url?value="/j_spring_security_logout"?/>">Logout System</a>
?
完全退出系統,并推出cas:
?
<p><a?href="https://sso.qau.edu.cn/cas/logout">Logout of CAS</a></p>
?
?
?
(6)方法中調用認證信息
?
-------------------------------------------------------------以下來自------------------------------------------
?
http://www.family168.com/tutorial/springsecurity3/html/cas.html
?
?
?
security?的中文翻譯文檔
?
Chapter?21.?CAS認證
?
21.1.?概述
?
JA-SIG開發了一個企業級的單點登錄系統,叫做CAS。?與其他項目不同,JA-SIG的中心認證服務是開源的,廣泛使用的,簡單理解的,不依賴平臺的,而且支持代理能力。?Spring Security完全支持CAS,提供一個簡單的整合方式,把使用Spring Security的單應用發布,轉換成使用企業級CAS服務器的多應用發布安全
?
你可以從http://www.ja-sig.org/cas/找到CAS的更多信息。?你還需要訪問這個網站下載CAS服務器文件。
?
21.2.?CAS是如何工作的
?
雖然CAS網站包含了CAS的架構文檔,我們這里還是說一下使用Spring Security環境的一般性概述,。?Spring Security 3.0支持CAS 3。?在寫文檔的時候,CAS服務器的版本是3.3。
?
你要在公司內部安裝CAS服務器。?CAS服務器就是一個WAR文件,所以安裝服務器沒有什么難的。?在WAR文件里,你需要自定義登錄和其他單點登錄展示給用戶的頁面。
?
發布CAS 3.3的時候,你也需要指定一個CAS的deployerConfigContext.xml里包含的AuthenticationHandler。?AuthenticationHandler有一個簡單的方法,返回布爾值,判斷給出的證書集合是否有效。?你的AuthenticationHandler實現會需要鏈接到后臺認證資源類型里,像是LDAP服務器或數據庫。?CAS自己也包含非常多AuthenticationHandler幫助實現這些。?在你下載發布服務器war文件的時候,它會把用戶名和密碼匹配的用戶成功驗證,這對測試很有用。
?
除了CAS服務器,其他關鍵角色當然是你企業發布的其他安全web應用。?這些web應用被叫做"services"。?這兒有兩種服務:標準服務和代理服務。?代理服務可以代表用戶,從其他服務中請求資源。?后面會進行更詳細的介紹。
?
21.3.?配置CAS客戶端
?
CAS的web應用端通過Spring Security使用起來很簡單。?我們假設你已經知道Spring Security的基本用法,所以下面都沒有涉及這些。?我們會假設使用基于命名空間配置的方法,并且添加了CAS需要的bean。
?
你需要添加一個?ServiceProperties?bean,到你的application context里。?這表現你的CAS服務:
?
? <bean id="serviceProperties"??????? class="org.springframework.security.cas.ServiceProperties">??? <property name="service"??????? value="https://localhost:8443/cas-sample/j_spring_cas_security_check"/>??? <property name="sendRenew" value="false"/>? </bean>????
這里的service必須是一個由CasAuthenticationFilter監控的URL。?這個sendRenew默認是false,但如果你的程序特別敏感就應該設置成true。?這個參數作用是,告訴CAS登錄服務,一個單點登錄沒有到達。?否則,用戶需要重新輸入他們的用戶名和密碼,來獲得訪問服務的權限。
?
下面配置的bean就是展開CAS認證的過程(假設你使用了命名空間配置):
?
<security:http entry-point-ref="casEntryPoint">?? ...?? <custom-filter position="FORM_LOGIN_FILTER" ref="myFilter" /></security:http>?<bean id="casFilter"????? class="org.springframework.security.cas.web.CasAuthenticationFilter">? <property name="authenticationManager" ref="authenticationManager"/></bean>?<bean id="casEntryPoint"??? class="org.springframework.security.cas.web.CasAuthenticationEntryPoint">? <property name="loginUrl" value="https://localhost:9443/cas/login"/>? <property name="serviceProperties" ref="serviceProperties"/></bean>?????
應該使用?entry-point-ref選擇驅動認證的CasAuthenticationEntryPoint類。
?
CasAuthenticationFilter的屬性與?UsernamePasswordAuthenticationFilter非常相似(在基于表單登錄時用到)。
?
為了CAS的操作,ExceptionTranslationFilter必須有它的AuthenticationEntryPoint,這里設置成CasAuthenticationEntryPoint?bean。
?
CasAuthenticationEntryPoint?必須指向?ServiceProperties?bean?(上面討論過了),它為企業CAS登錄服務器提供URL。?這是用戶瀏覽器將被重定向的位置。
?
下一步,你需要添加一個CasAuthenticationProvider?和它的合作伙伴:
?
? <security:authentication-manager alias="authenticationManager">??? <security:authentication-provider ref="casAuthenticationProvider" />? </security:authentication-manager>?? <bean id="casAuthenticationProvider"????? class="org.springframework.security.cas.authentication.CasAuthenticationProvider">??? <property name="userDetailsService" ref="userService"/>??? <property name="serviceProperties" ref="serviceProperties" />??? <property name="ticketValidator">????? <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator">??????? <constructor-arg index="0" value="https://localhost:9443/cas" />??????? </bean>??? </property>??? <property name="key" value="an_id_for_this_auth_provider_only"/>? </bean>?? <security:user-service id="userService">??? <security:user name="joe" password="joe" authorities="ROLE_USER" />??? ...? </security:user-service>??????
一旦通過了CAS的認證,CasAuthenticationProvider?使用一個?UserDetailsService實例,來加載用戶的認證信息。?這里我們展示一個簡單的基于內存的設置。
?
如果你翻回頭看一下"How CAS Works"那節,這些beans都是從名字就可以看懂的。
?
?
?
五、角色繼承(待整理)
?
?
?
在Spring Security中,我們可以指定角色間的繼承關系,這樣可以重用角色權限,減少配置的代碼量,讓權限配置整體上顯得更清晰。
?
為了使用角色繼承功能,我們需要對原有的配置文件進行一些修改。
?
<authentication-provider user-service-ref="userDetailsServiceWrapper"/>?<beans:bean id="userDetailsServiceWrapper"??? class="org.springframework.security.userdetails.hierarchicalroles.UserDetailsServiceWrapper">??? <beans:property name="userDetailsService" ref="userDetailsService"/>??? <beans:property name="roleHierarchy">??????? <beans:bean class="org.springframework.security.userdetails.hierarchicalroles.RoleHierarchyImpl">??????????? <beans:property name="hierarchy" value="ROLE_ADMIN > ROLE_USER"/>??????? </beans:bean>??? </beans:property></beans:bean>?<user-service id="userDetailsService">??? <user name="admin" password="admin" authorities="ROLE_ADMIN" />??? <user name="user" password="user" authorities="ROLE_USER" /></user-service>????????
我們將原有的user-service單獨抽離出來,在userDetailsService的基礎上生成一個userDetailsServiceWrapper,這個wrapper的作用就是在原有的user-service的基礎上啟用角色繼承功能。
?
我們使用RoleHierarchyImpl為userDetailsServiceWrapper配置了角色繼承的策略,ROLE_ADMIN > ROLE_USER表示ROLE_ADMIN將繼承ROLE_USER所有用的所有角色,只要是允許ROLE_USER訪問的資源,ROLE_ADMIN也都有權限進行訪問。這樣我們在user-service中的配置就可以從ROLE_ADMIN,ROLE_USER簡化為ROLE_ADMIN了,而intercept-url中的配置也可以從ROLE_ADMIN,ROLE_USER改為ROLE_USER了。
?
如果希望配置更多繼承關系,可以使用換行進行分隔,比如:
?
<property name="hierarchy">??? <value>??????? ROLE_A > ROLE_B??????? ROLE_B > ROLE_AUTHENTICATED??????? ROLE_AUTHENTICATED > ROLE_UNAUTHENTICATED??? </value></property>????????
?
?
?
?
第?51?章?角色繼承
?
有兩種方式可以用來實現角色繼承,一種是使用UserDetailsServiceWrapper在讀取用戶信息時,使用角色繼承為用戶賦予全部的權限,另一種是使用RoleHierarchyVoter在判斷權限的時候,使用角色繼承為生成繼承的全部權限。
?
使用UserDetailsServiceWrapper的情況,加載用戶信息的同時用戶會獲得所有權限,所以使用Acl的情況也不會出問題。使用RoleHierarchyVoter的情況,因為只會在每次校驗權限時才會使用繼承獲得所有權限,所以使用Acl的時候就會出現缺少權限的情況。
?
51.1.?使用RoleHierarchyVoter
?
把RoleHierarchyVoter加入配置文件中的accessDecisionManager。
?
<bean id="accessDecisionManager" class="org.springframework.security.vote.AffirmativeBased">
?
????<property name="allowIfAllAbstainDecisions" value="false"/>
?
????<property name="decisionVoters">
?
????????<list>
?
????????????<ref bean="roleHierarchyVoter"/>
?
????????????<ref bean="authenticatedVoter"/>
?
????????</list>
?
????</property>
?
</bean>
?
?
?
<bean id="roleHierarchyVoter" class="org.springframework.security.vote.RoleHierarchyVoter">
?
????<constructor-arg ref="roleHierarchy"/>
?
</bean>
?
?
?
<bean id="authenticatedVoter" class="org.springframework.security.vote.AuthenticatedVoter"/>
?
?
?
<bean id="roleHierarchy" class="org.springframework.security.userdetails.hierarchicalroles.RoleHierarchyImpl">
?
????<property name="hierarchy" value="ROLE_ADMIN > ROLE_USER"/>
?
</bean>
?
???????
?
然后在http中引用這個accessDecisionManager即可。
?
<http auto-config='true' access-decision-manager-ref='accessDecisionManager'>
?
????<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
?
????<intercept-url pattern="/**" access="ROLE_USER" />
?
</http>
?
???????
?
51.2.?使用數據庫實現RoleHierarchy
?
實現代碼來自http://jira.springframework.org/browse/SEC-1071。源代碼在http://forum.springsource.org/showthread.php?t=65515。
?
使用基于Dao的RoleHierarchy需要兩部設置。
?
第一是在數據庫中建立對應的表結構,并設置初始數據,數據庫表結構如下所示:
?
CREATE MEMORY TABLE ROLE_HIERARCHIES(
?
????INCLUDINGROLE VARCHAR(50),
?
????INCLUDEDROLE VARCHAR(50)
?
);
?
???????
?
includingrole表示繼承了其他角色的角色。includedrole表示被繼承的角色。如果我們希望設置ROLE_ADMIN繼承ROLE_USER,只需要進行如下設置。
?
INSERT INTO ROLE_HIERARCHIES(INCLUDINGROLE,INCLUDEDROLE) VALUES('ROLE_ADMIN','ROLE_USER')
?
???????
?
這樣RoleHierarchyEntryDaoJdbc會讀取數據庫中的數據,將其組裝成ROLE_ADMIN > ROLE_USER格式,再交給RoleHierarchyImpl進行分析,最終用于RoleHierarchyVoter完成角色繼承的判斷。
?
下面修改配置文件,將daoRoleHierarchy的bean設置到配置文件中。
?
<bean id="roleHierarchyVoter" class="org.springframework.security.vote.RoleHierarchyVoter">
?
????<constructor-arg ref="daoRoleHierarchy"/>
?
</bean>
?
?
?
<bean id="daoRoleHierarchy"
?
????class="org.springframework.security.userdetails.hierarchicalroles.RoleHierarchyImplDaoAware">
?
????<property name="_roleHierarchyEntryDao" ref="roleHierarchyEntryDaoJdbc"/>
?
</bean>
?
?
?
<bean id="roleHierarchyEntryDaoJdbc"
?
????class="org.springframework.security.userdetails.hierarchicalroles.RoleHierarchyEntryDaoJdbc">
?
????<property name="dataSource" ref="dataSource"/>
?
</bean>
?
???????
?
這樣就完成了使用數據庫保存角色繼承信息的功能。
?
?
?
?
?
六、角色分組功能(待整理)
?
?
?
使用用戶組
?
Spring Security提供了用戶組機制,可以將多個用戶歸納在一個組中,進行統一授權。下面我們來研究一下如何在數據庫中使用用戶組保存用戶的權限信息。
?
44.1.?數據庫結構
?
在原數據庫的基礎上添加用戶組所需的三張表:
?
create table groups (??? id bigint generated by default as identity(start with 0) primary key,??? group_name varchar_ignorecase(50) not null);?create table group_authorities (??? group_id bigint not null,??? authority varchar(50) not null,??? constraint fk_group_authorities_group foreign key(group_id) references groups(id));?create table group_members (??? id bigint generated by default as identity(start with 0) primary key,??? username varchar(50) not null,??? group_id bigint not null,??? constraint fk_group_members_group foreign key(group_id) references groups(id));????????
ER圖如下所示:
?
?
?
圖?44.1.?用戶組ER圖
?
?
?
下面開始初始化數據:
?
insert into users(username,password,enabled) values('admin','admin',true);insert into users(username,password,enabled) values('user','user',true);?insert into groups(id,group_name) values(1,'admin');insert into groups(id,group_name) values(2,'user');?insert into group_authorities(group_id,authority) values(1,'ROLE_ADMIN');insert into group_authorities(group_id,authority) values(2,'ROLE_USER');?insert into group_members(id,username,group_id) values(1,'admin',1);insert into group_members(id,username,group_id) values(2,'admin',2);insert into group_members(id,username,group_id) values(3,'user',2);????????
| ? | 創建兩個用戶admin和user。 |
| ? | 創建兩個組admin和user。 |
| ? | 為用戶組授權,讓admin組中的所有用戶都擁有ROLE_ADMIN權限,user組中的所有用戶都擁有ROLE_USER權限。 |
| ? | admin用戶加入admin和user兩個用戶組,將user用戶加入user用戶組。 |
?
44.2.?修改配置文件
?
為jdbc-user-service添加一個參數就可以打開用戶組功能。
?
<authentication-provider>??? <jdbc-user-service data-source-ref="dataSource"??????? group-authorities-by-username-query="??????????? SELECT g.id, g.group_name, ga.authority????????????? FROM groups g, group_members gm, group_authorities ga???????????? WHERE gm.username = ??????????????? AND g.id = ga.group_id?????????????? AND g.id = gm.group_id"/></authentication-provider>????????
這樣系統就會使用這條sql語句從用戶組表中查詢用戶擁有的權限。
?
之后可以啟動實例ch212,使用admin和user用戶測試授權情況。
?
?
?
?
?
七、ACL訪問控制列表(不同的人只能看到自己的信息)
?
http://www.family168.com/oa/springsecurity/html/ch301-acl.html
?
?
?
?
?
八、RESTful風格權限控制
?
RESTful是蠻流行的一種web資源訪問方式,它最大限度利用了http協議的功能表達資源請求的內涵。
?
- GET /app/messages:表示獲得所有Message的信息。
?
- GET /app/messages/1:表示獲得id=1的Message的信息。
?
- POST /app/messages:表示創建一條Message信息。
?
- PUT /app/messages/1:表示更新id=1的Message的信息。
?
- DELETE /app/messages/1:表示刪除id=1的Message的信息。
?
從上面的例子中可以看出來,我們只用了/app/messages和/app/messages/*兩類URL,就表示了Message的CRUD所有操作。這時如果我們希望對這些操作進行權限控制,就不能僅僅根據URL地址來判斷了,而是需要限制http請求的method參數。
?
下面我們對這些操作做出限制,只有ROLE_ADMIN才能添加,更新,刪除Message,ROLE_USER只能查看Message的信息。
?
<http auto-config='true'>??? <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />??? <intercept-url pattern="/app/messages" access="ROLE_ADMIN" method="POST" />??? <intercept-url pattern="/app/messages/*" access="ROLE_ADMIN" method="PUT" />??? <intercept-url pattern="/app/messages/*" access="ROLE_ADMIN" method="DELETE" />??? <intercept-url pattern="/**" access="ROLE_USER" /></http>????????
在intercept-url中使用method指定對應的http請求method參數就可以限制REST下定義的不同功能請求了,可以每次只能定義一個method,如果支持method="PUT,DELETE"這種形式的配置就更方便了。
?
實例參考x05。
?
?
?
【七】開發配置規范:
?
?
?
?
?
1.配置文件命名與位置
?
?
?
2.數據庫名
?
3.數據表名
?
?
?
4.類名
?
5.urls規劃
?
/模塊名/程序名/系列參數
?
?
?
?
?
6.文件名
總結
以上是生活随笔為你收集整理的Spring mvc 3.0 入门及应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 48幅非常搞笑的平面广告作品欣赏(上篇)
- 下一篇: pci驱动与硬件通信