spring security4.2.2的maven配置+spring-security配置詳解+java源碼+數據庫設計

1、引子

      最近項目須要添加權限攔截,經討論決定採用spring security4.2.2!廢話少說直接上乾貨!css

      spring security 4.2.2文檔:http://docs.spring.io/spring-security/site/docs/4.2.2.RELEASE/reference/htmlsingle/#el-access-webhtml

      spring security 3 中文2文檔:http://www.mossle.com/docs/auth/html/index.htmljava

2、pom.xml配置

      須要在pom.xml裏配置spring security的依賴,能夠經過http://mvnrepository.com/search?q=spring+securitye查詢不一樣版本須要的spring的版本支持。jquery

 1   <!--spring security  -->
 2         <dependency>
 3             <groupId>org.springframework.security</groupId>
 4             <artifactId>spring-security-core</artifactId>
 5             <version>4.2.2.RELEASE</version>
 6         </dependency>
 7         
 8         <dependency>
 9             <groupId>org.springframework.security</groupId>
10             <artifactId>spring-security-web</artifactId>
11             <version>4.2.2.RELEASE</version>
12         </dependency>
13         
14          <dependency>
15             <groupId>org.springframework.security</groupId>
16             <artifactId>spring-security-config</artifactId>
17             <version>4.2.2.RELEASE</version>
18         </dependency>
19         <dependency>
20             <groupId>org.springframework.security</groupId>
21             <artifactId>spring-security-taglibs</artifactId>
22             <version>4.2.2.RELEASE</version>
23         </dependency>

3、web.xml配置       

須要在web.xml中配置Spring Security控制權限過濾器,web

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>  

4、spring-security.xml配置

下面最主要的就是spring-security.xml的配置了算法

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
  3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4     xmlns="http://www.springframework.org/schema/security"
  5     xsi:schemaLocation="http://www.springframework.org/schema/beans
  6             http://www.springframework.org/schema/beans/spring-beans.xsd
  7             http://www.springframework.org/schema/security
  8             http://www.springframework.org/schema/security/spring-security.xsd" >
  9     
 10     <!-- 打印調試信息,僅在開發環境中使用 -->
 11     <!-- <debug/> -->
 12     
 13     <!-- 不須要被攔截的請求 -->
 14     <http pattern="/loginPage" security="none"/>
 15     <http pattern="/scripts/**" security="none"/>
 16     
 17     <!-- 
 18         登陸頁面可使用第一種:
 19         <http pattern="/login.jsp" security="none"></http>
 20         <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?error=true" ......
 21         這種方式直接訪問.jsp
 22         也可使用Controller來控制,兩種方式登陸頁面login.jsp的位置不同!!!
 23         下面是第二種方式:
 24         <http pattern="/login" security="none"></http>
 25         <form-login login-page="/login" login-processing-url="/login" ......
 26         第一個配置告訴spring security,相似於/login的url請求不作過濾處理,而第二個配置信息又告訴spring security url爲/login的post請求登陸請求處理。正是這種衝突致使了405錯誤的發生。
 27         既然知道了錯誤緣由,那麼只要避免衝突就能解決這個問題:使登陸頁的請求和登陸處理的請求不一致,而後只配置登陸頁的請求不作攔截處理.
 28         我採用的方法是使用默認的登陸URL /login,修改登陸頁面跳轉url爲/loginPage。請自行修改代碼和配置信息
 29         這樣是否是就大工告成了呢?很遺憾,當你啓動程序時,輸出用戶名和密碼,無論正確與否,都會有404 Not Found等着你,這又是爲何呢?
 30         登陸請求404錯誤
 31         首先,建議你看一下spring security自動生成的登陸頁源碼,你會發現有以下代碼
 32         <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
 33         對於什麼是csrf,請自行參考網上的資料。
 34         spring security默認狀況下csrf protection是開啓的,因爲咱們的登陸頁沒有配置csrf的相關信息,所以spring security內置的過濾器將此連接置爲無效連接
 35         解決辦法就是配置csrf protection爲不可用狀態,在配置文件中增長
 36         <csrf disabled="true"/>
 37     -->
 38     
 39     <!-- 
 40         一、<http auto-config="true">,他能夠自動配置login form,BSIC 認證和logout URL 和logout services,若是沒有特殊代表,這個的默認值是false。想要本身配置則設置爲"true"
 41         二、Spring Security採用的是一種就近原則,就是說當用戶訪問的url資源知足多個intercepter-url時,系統將使用第一個符合條件的intercept-url進行權限控制
 42      -->
 43     <http  auto-config="true" use-expressions="true">
 44         <!--
 45             另外一種權限表達式:
 46             <http use-expressions="false">
 47             <intercept-url pattern='/**' access='ROLE_USER' />
 48         -->
 49         <!-- 禁用CSRF保護,默認是啓用 -->
 50         <csrf disabled="true"/>
 51         
 52         <anonymous enabled="false"/>
 53         
 54         <!-- 基於角色認證(必須擁有ROLE_XXX角色才能訪問全部/**/XXX/**資源) -->
 55         <!-- 確保對功能URL訪問都須要權限 -->
 56         <intercept-url pattern="/**/add/**" access="hasRole('ADD')"/>
 57         <intercept-url pattern="/**/update/**" access="hasRole('UPDATE')"/>
 58         <intercept-url pattern="/**/delete/**" access="hasRole('DELETE')"/>
 59         <intercept-url pattern="/**/download/**" access="hasRole('DOWNLOAD')"/>  
 60         <intercept-url pattern="/**/access/**" access="hasRole('ADMIN')"/>
 61         
 62         <!-- Ensures that any request to our application requires the user to be authenticated  -->
 63         <intercept-url pattern="/**" access="authenticated"/>
 64 
 65         
 66         <!-- 
 67             實現免登錄驗證,默認有效時間是兩週,啓用rememberMe以後的兩週內,用戶均可以直接跳過系統,直接進入系統。
 68             實際上,Spring Security中的rememberMe是依賴cookie實現的,當用戶在登陸時選擇使用rememberMe,系統就會在登陸成功後將爲用戶生成一個惟一標識,並將這個標識保存進cookie中
 69             Spring Security生成的cookie名稱是SPRING_SECURITY_REMEMBER_ME_COOKIE,它的內容是一串加密的字符串,
 70             當用戶再次訪問系統時,Spring Security將從這個cookie讀取用戶信息,並加以驗證。若是能夠證明cookie有效,就會自動將用戶登陸到系統中,併爲用戶授予對應的權限。
 71         -->
 72 
 73         <!--   
 74             <remember-me remember-me-parameter="remember-me"
 75             data-source-ref="dataSource"/>
 76             spring security還提供了remember me的另外一種相對更安全的實現機制 :在客戶端的cookie中,僅保存一個無心義的加密串(與用戶名、密碼等敏感數據無關),而後在db中保存該加密串-用戶信息的對應關係,自動登陸時,用cookie中的加密串,到db中驗證,若是經過,自動登陸纔算經過。會自動在你的數據庫裏建立一個表:PERSISTENT_LOGINS。
 77             若是不加data-source-ref="dataSource",會將上述信息放在內存中!
 78             做者的項目有些特殊要求,全部採用了下面的方式:登陸後要在myAuthenticationSuccessHandler作特殊的處理!
 79         -->
 80         <remember-me authentication-success-handler-ref="myAuthenticationSuccessHandler"/>
 81 
 82         <!-- 
 83             login-page : 表示用戶登錄時顯示咱們自定義的登陸頁面
 84             authentication-failure-url : 登陸認證失敗轉向的url,當用戶輸入的登陸名和密碼不正確時,系統將再次跳轉到登陸頁面,並添加一個error=true參數做爲登錄失敗的標示,這個標識是咱們自定義的。
 85             default-target-url : 登陸認證成功轉向的地址
 86          -->
 87         <form-login 
 88             login-page="/loginPage" 
 89             authentication-failure-url="/loginPage?error=true" 
 90             authentication-success-handler-ref="myAuthenticationSuccessHandler"  
 91         />
 92         
 93         <!-- 登出後,返回到登錄頁面 -->
 94         <!--  <logout logout-success-url="/loginPage" logout-url="/logout"/>
 95                    delete-cookies="JSESSIONID":退出刪除JSESSIONID
 96         -->
 97         <logout />
 98         <!-- 
 99             控制同步session的過濾器 
100             若是concurrency-control標籤配置了error-if-maximum-exceeded="true",max-sessions="1",那麼第二次登陸時,是登陸不了的。
101             若是error-if-maximum-exceeded="false",那麼第二次是可以登陸到系統的,
102             可是第一個登陸的帳號再次發起請求時,會跳轉到expired-url配置的url中,
103             若是沒有配置expired-url,則顯示:
104             This session has been expired (possibly due to multiple concurrent logins being attempted as the same user).
105             翻譯過來意思就是說:這個會話已通過期(可能因爲多個併發登陸嘗試相同的用戶)
106          -->
107        
108         <session-management invalid-session-url="/loginPage" >
109             <concurrency-control max-sessions="1" error-if-maximum-exceeded="false" expired-url="/loginPage"/>
110         </session-management>
111         
112         <!-- 指定本身的權限驗證過濾器,首先走本身的的過濾器 myFilter,若是被攔截就報沒有權限;
113              若是經過會走spring security自帶的攔截器,即上面配置的權限配置!
114         -->
115         <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="myFilter"/>
116     </http>
117     
118     <!-- 權限認證Spring日誌監聽器  -->
119     <beans:bean class="org.springframework.security.authentication.event.LoggerListener"/>
120     <beans:bean class="org.springframework.security.access.event.LoggerListener"/>
121     
122     <!--
123              一個自定義的filter,必須包含authenticationManager,accessDecisionManager,securityMetadataSource三個屬性,
124          咱們的全部控制將在這三個類中實現,解釋詳見具體配置。
125     -->
126     <beans:bean id="myFilter" class="com.tcbd.common.interceptor.MyFilterSecurityInterceptor" >
127         <beans:property name="authenticationManager" ref="authenticationManager" />
128         <beans:property name="accessDecisionManager" ref="myAccessDecisionManagerBean" />
129         <beans:property name="securityMetadataSource" ref="securityMetadataSource" />
130     </beans:bean>
131 
132     <!-- 驗證配置,實現用戶認證的入口,主要實現UserDetailsService接口便可  -->
133     <authentication-manager alias="authenticationManager" >
134         <authentication-provider ref="daoAuthenticationProvider" >
135         </authentication-provider> 
136     </authentication-manager>
137 
138     <beans:bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
139         <beans:property name="userDetailsService" ref="myUserDetailService" />
140         <beans:property name="passwordEncoder" ref="passwordEncoder" />
141     </beans:bean>    
142     <!-- spring推薦的單向加密算法 -->
143     <beans:bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
144     
145     <!-- 在這個類中,讀入用戶的密碼,角色信息,是否鎖定,帳號是否過時等屬性信息  -->
146     <beans:bean id="myUserDetailService" class="com.tcbd.common.interceptor.MyUserDetailService" />
147     
148     
149     <!-- 訪問決策器,決定某個用戶具備的角色,是否有足夠的權限去訪問某個資源 -->
150     <beans:bean id="myAccessDecisionManagerBean" class="com.tcbd.common.interceptor.MyAccessDecisionManager" ></beans:bean>
151 
152     <!-- 資源源數據定義,即定義某一資源能夠被哪些角色訪問 -->
153     <beans:bean id="securityMetadataSource" class="com.tcbd.common.interceptor.MyFilterSecurityMetadataSource" />
154     
155     <beans:bean id="myAuthenticationSuccessHandler" class="com.tcbd.common.interceptor.MyAuthenticationSuccessHandler"/>
156     
157 </beans:beans>

spring security爲咱們提供了三種通配符。
通配符:?
示例:/admin/g?t.jsp
匹配任意一個字符,/admin/g?t.jsp能夠匹配/admin/get.jsp和/admin/got.jsp或是/admin/gxt.do。不能匹配/admin/xxx.jsp。
通配符:*
示例:/admin/*.jsp
匹配任意多個字符,但不能跨越目錄。/*/index.jsp能夠匹配/admin/index.jsp和/user/index.jsp,可是不能匹配/index.jsp和/user/test/index.jsp。
通配符:**
示例:/**/index.jsp
能夠匹配任意多個字符,能夠跨越目錄,能夠匹配/index.jsp,/admin/index.jsp,/user/admin/index.jsp和/a/b/c/d/index.jspspring

5、本身的攔截器

1,讀入用戶的密碼,角色信息,是否鎖定,帳號是否過時等屬性信息 :MyUserDetailService 

 1 import java.util.ArrayList;
 2 import java.util.Collection;
 3 
 4 import javax.annotation.Resource;
 5 
 6 import org.apache.commons.lang.StringUtils;
 7 import org.apache.log4j.Logger;
 8 import org.springframework.dao.DataAccessException;
 9 import org.springframework.security.core.GrantedAuthority;
10 import org.springframework.security.core.authority.SimpleGrantedAuthority;
11 import org.springframework.security.core.userdetails.User;
12 import org.springframework.security.core.userdetails.UserDetails;
13 import org.springframework.security.core.userdetails.UserDetailsService;
14 import org.springframework.security.core.userdetails.UsernameNotFoundException;
15 
16 /**
17  * 從數據庫中讀入用戶的密碼,角色信息,是否鎖定,帳號是否過時等
18  * 
19  */
20 public class MyUserDetailService implements UserDetailsService {
21     @Resource
22     private UserService userService;
23 
24     /**
25      * 數據庫交互獲取用戶擁有的權限角色,並設置權限
26      */
27     @Override
28     public UserDetails loadUserByUsername(String userCode) throws UsernameNotFoundException, DataAccessException {
29         // 根據登陸用戶名獲取用戶信息
30         Users user = new Users();
31         user.setUserCode(username);
32         user = userService.selectByModel(user);
33         if (null != user) {
34             // 存放權限
35             Collection<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
36                 String action = user.getRole();
37                 if (StringUtils.isNotBlank(action)) {
38                     String[] roleaCtion = action.split(",");
39                     for (int i = 0; i < roleaCtion.length; i++) {
40                         SimpleGrantedAuthority auth = new SimpleGrantedAuthority(roleaCtion[i]);
41                         auths.add(auth);
42                     }
43                 }
44                 //spring security自帶的User對象
45             User userDetails = new User(username, user.getPassword(), true, true, true, true, auths);
46             return userDetails;
47         }
48         return null;
49     }
50 }

2,定義某一資源能夠被哪些角色訪問:MyFilterSecurityMetadataSource

 1 import java.util.ArrayList;
 2 import java.util.Collection;
 3 import java.util.List;
 4 import java.util.Map;
 5 
 6 import javax.servlet.http.HttpServletRequest;
 7 
 8 import org.apache.log4j.Logger;
 9 import org.springframework.security.access.ConfigAttribute;
10 import org.springframework.security.access.SecurityConfig;
11 import org.springframework.security.web.FilterInvocation;
12 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
13 
14 public class MyFilterSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
15     private static Logger logger = Logger.getLogger(MyFilterSecurityMetadataSource.class);
16 
17     public List<ConfigAttribute> getAttributes(Object object) {
18         FilterInvocation fi = (FilterInvocation) object;
19         HttpServletRequest request = fi.getRequest();
20         String requestUrl = fi.getRequest().getRequestURI();
21         List<ConfigAttribute> attributes = new ArrayList<ConfigAttribute>();
22         // 全部URL對應的角色,應用啓動就存放到靜態資源裏,獲得的結果是:不一樣的URL下,包含的多個角色
23         Map<String, String> resRoles = Constant.URL_ROLES;
24 
25         for (Map.Entry<String, String> ent : resRoles.entrySet()) {
26             String url = ent.getKey();
27             String roles = ent.getValue();
28             //根據業務寫本身的匹配邏輯
29             if(requestUrl.startsWith(url)){
30                 attributes.addAll(SecurityConfig.createListFromCommaDelimitedString(roles));
31             }
32         }
33         logger.debug("【"+request.getRequestURI()+"】 roles: "+attributes);
34         return attributes;
35     }
36 
37 
38     public Collection<ConfigAttribute> getAllConfigAttributes() {
39         return null;
40     }
41 
42     public boolean supports(Class<?> clazz) {
43         return FilterInvocation.class.isAssignableFrom(clazz);
44     }
45 }

3,訪問決策器,決定某個用戶具備的角色,是否有足夠的權限去訪問某個資源:MyAccessDecisionManager 

 

 1 import java.util.Collection;
 2 import java.util.Iterator;
 3 
 4 import org.apache.commons.logging.Log;
 5 import org.apache.commons.logging.LogFactory;
 6 import org.springframework.security.access.AccessDecisionManager;
 7 import org.springframework.security.access.AccessDeniedException;
 8 import org.springframework.security.access.ConfigAttribute;
 9 import org.springframework.security.access.SecurityConfig;
10 import org.springframework.security.authentication.InsufficientAuthenticationException;
11 import org.springframework.security.core.Authentication;
12 import org.springframework.security.core.GrantedAuthority;
13 
14 /**
15  * 在這種方法中,須要與configAttributes比較驗證
16  * 一、一個對象是一個URL,一個過濾器被這個URL找到權限配置,並經過這裏
17  * 二、若是沒有匹配相應的認證,AccessDeniedException
18  * 
19  */
20 public class MyAccessDecisionManager implements AccessDecisionManager {
21 
22     private static final Log logger = LogFactory.getLog(MyAccessDecisionManager.class);
23     
24     /**
25      * 在這個類中,最重要的是decide方法,若是不存在對該資源的定義,直接放行; 不然,若是找到正確的角色,即認爲擁有權限,並放行,不然throw
26      * new AccessDeniedException("no right");這樣,就會進入上面提到的/accessDenied.jsp頁面。
27      * @param authentication :當前用戶所且有的角色
28      * @param object :當前請求的URL
29      * @param configAttributes :當前URL所且有的角色
30      */
31     @Override
32     public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
33             throws AccessDeniedException, InsufficientAuthenticationException {
34         // 資源所需的角色列表,若是角色列表爲空,則放行!繼續下一個攔截器。
35         if (configAttributes == null) {
36             return;
37         }
38         // 即將訪問的資源URL,如 : /admin.jsp
39         logger.info("URL :"+object);
40         // 遍歷所需的角色集合
41         Iterator<ConfigAttribute> ite = configAttributes.iterator();
42         while (ite.hasNext()) {
43             ConfigAttribute ca = ite.next();
44             // 該資源所須要的角色
45             String needRole = ((SecurityConfig) ca).getAttribute();
46             // authentication.getAuthorities()獲取用戶所擁有的角色列表,如:OLE_DEFULT
47             for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
48                 // 將資源所須要的角色與用戶擁有的角色比較
49                 if (needRole.equals(grantedAuthority.getAuthority())) {
50                     // grantedAuthority is user's role.
51                     // 角色相同,直接放行
52                     return;
53                 }
54             }
55         }
56         // 不然,提示沒有權限訪問該資源
57         throw new AccessDeniedException("no right");
58     }
59 
60     @Override
61     public boolean supports(ConfigAttribute attribute) {
62         return true;
63     }
64 
65     @Override
66     public boolean supports(Class<?> clazz) {
67         return true;
68     }
69 
70 }

4,攔截器核心,MyFilterSecurityInterceptor

 1 import java.io.IOException;
 2 
 3 import javax.servlet.Filter;
 4 import javax.servlet.FilterChain;
 5 import javax.servlet.FilterConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.ServletRequest;
 8 import javax.servlet.ServletResponse;
 9 
10 import org.springframework.security.access.SecurityMetadataSource;
11 import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
12 import org.springframework.security.access.intercept.InterceptorStatusToken;
13 import org.springframework.security.web.FilterInvocation;
14 import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
15 
16 /**
17  * 
18  */
19 public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor
20         implements Filter {
21     
22     private FilterInvocationSecurityMetadataSource securityMetadataSource;
23 
24     /* get、set方法 */
25     public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
26         return securityMetadataSource;
27     }
28 
29     public void setSecurityMetadataSource(
30             FilterInvocationSecurityMetadataSource securityMetadataSource) {
31         this.securityMetadataSource = securityMetadataSource;
32     }
33 
34     @Override
35     public Class<? extends Object> getSecureObjectClass() {
36         return FilterInvocation.class;
37     }
38 
39     @Override
40     public SecurityMetadataSource obtainSecurityMetadataSource() {
41         return this.securityMetadataSource;
42     }
43 
44     @Override
45     public void doFilter(ServletRequest request, ServletResponse response,
46             FilterChain chain) throws IOException, ServletException {
47         
48         FilterInvocation fi = new FilterInvocation(request, response, chain);
49         invoke(fi);
50     }
51 
52     public void invoke(FilterInvocation fi) throws IOException,
53             ServletException {
54         /**
55          * 最核心的代碼就是@link InterceptorStatusToken token = super.beforeInvocation(fi);
56          * 它會調用咱們定義的MyInvocationSecurityMetadataSource.getAttributes方法和MyAccessDecisionManager.decide方法
57          * 這一句,即在執行doFilter以前,進行權限的檢查,而具體的實現已經交給@link MyAccessDecisionManager 了
58          */
59         InterceptorStatusToken token = super.beforeInvocation(fi);
60         try {
61             //繼續走下一個攔截器,也就是org.springframework.security.web.access.intercept.FilterSecurityInterceptor
62             fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
63         } finally {
64             super.afterInvocation(token, null);
65         }
66     }
67 
68     @Override
69     public void destroy() {
70 
71     }
72 
73     @Override
74     public void init(FilterConfig arg0) throws ServletException {
75 
76     }
77 
78 }

5,登陸頁面(須要本身改一些東西)

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib prefix='fmt' uri="http://java.sun.com/jsp/jstl/fmt" %>
 4 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 5 <%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
 6 <!DOCTYPE html>
 7 <html lang="zh-CN">
 8   <head>
 9     <meta charset="utf-8">
10     <meta http-equiv="X-UA-Compatible" content="IE=edge">
11     <meta name="viewport" content="width=device-width, initial-scale=1">
12     <!-- 上述3個meta標籤*必須*放在最前面,任何其餘內容都*必須*跟隨其後! -->
13     <meta name="description" content="">
14     <meta name="author" content="">
15     <link rel="icon" href="/favicon.ico">
16 
17     <title><fmt:message key="application.title"></fmt:message></title>
18 
19     <!-- Bootstrap core CSS -->
20     <link href="/scripts/plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet">
21 
22     <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
23     <!-- Custom styles for this template -->
24     
25     <link href="/scripts/apps/css/signin.css" rel="stylesheet">
26     
27     <style type="text/css">
28     .tip {
29         font-size: 10px;
30         color: red;
31         text-align: center;
32     }
33     
34     </style>
35   </head>
36 
37   <body>
38     <div class="container">
39         <c:url var="loginUrl" value="/login" />
40       <form action="${loginUrl}" id="login_form" class="form-signin" method="post">
41           <div class="form-signin-heading text-center">
42             <h2 ><fmt:message key="application.title"></fmt:message></h2>
43           </div>
44           <div id="tip" class="tip"></div>
45           <c:if test="${param.error != null}">
46                 <span style="color:red">用戶名或密碼有誤</span>
47         </c:if>
48         
49         <label for="inputEmail" class="sr-only">登陸賬號</label>
50         <input type="text" id="inputUserCode" name="username" class="form-control" placeholder="登陸賬號"  autofocus>
51            <label for="inputPassword" class="sr-only">登陸密碼</label>
52            <input type="password" id="inputPassword" name="password" class="form-control" placeholder="登陸密碼">
53         <div class="input-group input-sm">
54           <div class="checkbox">
55             <label><input type="checkbox" id="rememberme" name="remember-me" value="true"> 下次自動登陸</label>  
56           </div>
57         </div>
58         <button id="login_button" class="btn btn-lg btn-primary btn-block" type="submit">登陸</button>
59       </form>
60 
61     </div> 
62  
63     <script src="/scripts/plugins/jQuery/jquery-2.2.3.min.js"></script>
64   </body>
65 </html>

在JSP中相應的操做按鈕上加上以下標籤,控制顯示:數據庫

<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%> 該標籤必定要加上!!!
<sec:authorize access="hasRole('ADD')">
<a href="/XXX/add">增長</a>
</sec:authorize>express

    數據庫設計:user表裏有roleId,role表,resource-role表,resource表apache

相關文章
相關標籤/搜索