springMvc的安全登入驗證
阿新 • • 發佈:2019-02-08
1. 引入springMvc許可權框架security
1-1 配置web.xml
1. 在監聽器上引入許可權局框架的配置檔案security.xml <!--監聽器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:security.xml</param-value> </context-param> 注意 :<param-value>標籤可以配置多個配置檔案,一般用逗號隔開 2. 配置過濾器 <!--filter許可權框架過濾器執行鏈--> <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> 注意:filter許可權框架執行鏈要放在解決亂碼的CharacterEncodingFilter過濾器下面,否則會出現中文亂碼
1-2 配置security框架的xml檔案security.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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <!--放行頁面不被許可權框架攔截驗證--> <security:http pattern="/login.jsp" security="none"></security:http> <security:http pattern="/failer.jsp" security="none"></security:http> <security:http pattern="/css/**" security="none"></security:http> <security:http pattern="/img/**" security="none"></security:http> <security:http pattern="/plugins/**" security="none"></security:http> <security:http pattern="/pages/**" security="none"></security:http> <!--配置攔截的規則 auto-config="true" 開啟框架的預設配置支援 use-expressions="false" 關閉表示式的支援 intercept-url pattern="/**" 攔截所有的請求 access="ROLE_USER" 擁有ROLE_USER角色的使用者可以訪問資源 --> <security:http auto-config="true" use-expressions="true"> <!--使用springmvc提供的記住登入功能, user-service-ref對映到許可權實現類userService key 瀏覽器訪問存的cookie名稱,隨便起個名字,不用管 login.jsp裡面記住我複選框checkbox的name屬性必須是“remember-me”,其他無效 --> <security:remember-me user-service-ref="userService" key="rememberUser"></security:remember-me> <!--給角色賦予許可權--> <security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ORDER','ROLE_ADMIN','ROLE_PRODUCT')"></security:intercept-url> <!--配置許可權框架自定義面登入節點 login-page 自定義登入頁 login-processing-url 登入頁面表單發起登入請求的url路徑 default-target-url 登入成功跳轉的頁面 authentication-failure-url 驗證失敗跳轉的頁面 --> <security:form-login login-page="/login.jsp" login-processing-url="/login" default-target-url="/index.jsp" authentication-failure-url="/failer.jsp"></security:form-login> <!--登出按鈕的處理節點--> <security:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"></security:logout> <!--訪問資源無許可權拒絕的處理--> <security:access-denied-handler error-page="/403.jsp"></security:access-denied-handler> <!--csrf攻擊攔截的關閉--> <security:csrf disabled="true"></security:csrf> </security:http> <!--許可權驗證使用自定義的實現類,這裡配置的是userService作為許可權實現類--> <security:authentication-manager> <security:authentication-provider user-service-ref="userService"> <!-- 提供加密方式 --> <security:password-encoder ref="pwdEncoder"></security:password-encoder> </security:authentication-provider> </security:authentication-manager> <security:global-method-security secured-annotations="enabled"></security:global-method-security> <!--通過xml檔案初始化加密的工具類交給容器管理--> <bean id="pwdEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></bean> </beans>
2. 許可權驗證類UserService的編寫
@Service("userService") @Transactional public class userServiceImpl implements UserService ,UserDetailsService { @Autowired private UserDao userDao; @Autowired BCryptPasswordEncoder pwdEncoder; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { // 通過使用者名稱得到資料庫使用者物件 SysUser sysUser = userDao.findUserByName(username); // 建立使用者的許可權集合 List<GrantedAuthority> authorities = new ArrayList<>(); // 查詢到使用者的角色驗證登入 List<Role> userRoles = sysUser.getRoles(); // 迴圈新增使用者的角色資訊 if (userRoles.size()>0 && userRoles != null) { for (Role userRole : userRoles) { // 初始化賦值給使用者角色 authorities.add(new SimpleGrantedAuthority(userRole.getRoleName())); } } // 使用資料庫使用者組裝框架需要的user物件用於驗證 User user = new User(sysUser.getUsername(), sysUser.getPassword(), authorities); return user; // 返回值user帶有使用者名稱username,密碼password和角色即許可權authorties,返回的user是UserDetails 物件,由框架獲取操縱 } /** 新增一個使用者,密碼使用BCryptPasswordEncoder 加密,由於在security.xml配置了加密方式,所以登入框架幫你解密,不用管 login.jsp登入的form表單提交到在security.xml已經配置好了的"${pageContext.request.contextPath}/login" */ @Override public void addUser(SysUser user) { //將原始密碼獲取 String pwd = user.getPassword(); //將明文加密 user.setPassword( pwdEncoder.encode(pwd)); userDao.addUser(user); }
3.許可權的控制
3-1.頁面許可權的控制
1.引入標籤庫
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
2.表示式驗證
<security:authorize access="hasRole('ROLE_ADMIN')">
// 要被許可權框架控制的程式碼
</security:authorize>
例如:
<security:authorize access="hasAnyRole('ROLE_ADMIN')">
<!-- 只有擁有ROLE_ADMIN角色的使用者才能顯示-->
<li id="system-setting4">
<a href="${pageContext.request.contextPath}/pages/syslog-list.jsp"> <i class="fa fa-circle-o"></i> 訪問日誌
</a></li>
</security:authorize>
3.security.xml檔案中開啟表示式支援
// use-expressions="true" 就是開啟表示式支援,完整的上面的security有
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ORDER','ROLE_ADMIN','ROLE_PRODUCT')"> </security:intercept-url>
3-2 .後臺程式碼許可權控制
在頁面配置的許可權管理後雖然對沒有許可權的訪問者予以限制,但是仍然可以通過在瀏覽器位址列上訪問路徑,所以使用後臺許可權控制尤為主要
通過三種註解實現許可權的攔截:
1.jsr250的方式實現攔截 jsr是java的一個規範 jsr250是對規範的實現 目的是攔截驗證許可權
引入依賴
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
在配置檔案中開啟註解支援 為了攔截controller方法配置springMvc中
約束檔案和名稱空間
xmlns:security="http://www.springframework.org/schema/security"
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
<security:global-method-security jsr250-annotations="enabled"/>
在需要攔截的類或者方法上通過表示式攔截認證
@RolesAllowed("ROLE_ADMIN")
2.secured 註解攔截
<security:global-method-security secured-annotations="enabled"/>
@Secured("ROLE_ADMIN")
3.表示式的註解攔截
<security:global-method-security pre-post-annotations="enabled"/>
@PreAuthorize("hasRole('ROLE_ADMIN')")
注意:
1、三種方式都必須在springMvc.xml配置檔案中開啟註解支援
<!-- 開啟AOP的支援 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
2、推薦使用第二種,次之第三種,不推薦第一種方式,太麻煩了