SpringSecurity基礎使用
SpringSecurity是一個安全框架,主要功能是認證和授權
從Spring入手SpringSecurity
1. Spring整合SpringSecurity
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.shaoby.service"></context:component-scan><import resource="spring-security.xml"/>
</beans>
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 啟用注解掃描 --><context:component-scan base-package="com.shaoby.controller" /><!-- 配置視圖解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/views/" /><property name="suffix" value=".jsp" /></bean><!-- 啟用Spring MVC的注解 --><mvc:annotation-driven /><!-- 定義控制器 -->
<!-- <bean name="/example" class="com.shaoby.controller.ExampleController" />--></beans>
spring-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><remember-metoken-validity-seconds="60"remember-me-parameter="remember-me"/><access-denied-handler error-page="/error.jsp"/></http><authentication-manager><authentication-provider><user-service><user name="user" password="{noop}123" authorities="ROLE_USER" /></user-service></authentication-provider></authentication-manager></beans:beans>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><display-name>Archetype Created Web Application</display-name>
<!-- 初始化web容器--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!--配置Spring的監聽器,默認只加載WEB-INF目錄下的applicationContext.xml配置文件--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
<!--亂碼--><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>characterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
<!--security--><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>
<!--前端控制器--><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>
2. 認證操作
2.1 自定義登錄頁面
自定義登錄頁面只需要在security配置文件中指定登錄頁面即可
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><!--指定登錄頁面或登錄成功頁面等,都在這個標簽中可以指定--><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><!-- 錯誤頁面--><access-denied-handler error-page="/error.jsp"/></http><authentication-manager><authentication-provider><user-service><user name="user" password="{noop}123" authorities="ROLE_USER" /></user-service></authentication-provider></authentication-manager>
</beans:beans>
2.2 關閉CSRF認證
使用csrf標簽指定disabled = 'true’即可
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><!--指定登錄頁面或登錄成功頁面等,都在這個標簽中可以指定--><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><!-- 錯誤頁面--><access-denied-handler error-page="/error.jsp"/><!--關閉CSRF認證--><csrf disabled="true"/></http><authentication-manager><authentication-provider><user-service><user name="user" password="{noop}123" authorities="ROLE_USER" /></user-service></authentication-provider></authentication-manager>
</beans:beans>
如果在JSP頁面中也可以通過引入標簽解決
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-#引入
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<html>
<head><title>登錄</title>
</head>
<body>
<h1>登錄頁面</h1>
<form action="/login" method="post">賬號:<input type="text" name="username"/> <br>密碼:<input type="password" name="password"/> <br>-#使用標簽<security:csrfInput/><input type="submit" value="登錄">
</form>
</body>
</html>
2.3 持久層認證
- 認證一般是通過持久層查詢進行認證的,這里暫時沒有鏈接數據庫,將數據寫死。
- ecurity實現持久層的認證只需要實現UserDetailsService,重寫loadUserByUserName,返回一個UserDetails對象即可,這個UserDetails對象可以通過任何方式獲得,一般是數據庫根據登錄用戶名查詢。
- 需要注意的是,如果密碼沒有采用加密方式,密碼前必須拼接{noop}字符串。
- 將寫好的實現類給Security指定
@Service
public class UserServiceImpl implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {List<GrantedAuthority> list = new ArrayList<>();list.add(new SimpleGrantedAuthority("ROLE_USER"));UserDetails user = new User("admin", "{noop}123456", list);return user;}
}
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><!--指定登錄頁面或登錄成功頁面等,都在這個標簽中可以指定--><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><!-- 錯誤頁面--><access-denied-handler error-page="/error.jsp"/><!--關閉CSRF認證--><csrf disabled="true"/></http><authentication-manager><!--指定認證的類--><authentication-provider user-service-ref="userServiceImpl"></authentication-provider></authentication-manager>
</beans:beans>
2.4 密碼加密
- 密碼加密的方式有很多,比如MD5、MD4、BCryptPasswordEncoder等
- 如果使用加密的方式,一般是在持久層存儲的就是加密后的數據
- 使用加密的方法
- 將加密的方式注入到spring容器中
- 然后給Security指定加密方式
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsd"><context:component-scan base-package="com.shaoby.service"></context:component-scan>
<!--使用的加密方式的類--><bean name="bCryptPasswordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/><import resource="spring-security.xml"/>
</beans>
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><!--指定登錄頁面或登錄成功頁面等,都在這個標簽中可以指定--><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><!-- 錯誤頁面--><access-denied-handler error-page="/error.jsp"/><!--關閉CSRF認證--><csrf disabled="true"/></http><authentication-manager><!--指定認證的類--><authentication-provider user-service-ref="userServiceImpl"><!--給security指定加密的方式--><password-encoder ref="bCryptPasswordEncoder"/></authentication-provider></authentication-manager>
</beans:beans>
2.5 remember me
- 這個功能是在頁面勾選’記住我‘的勾選框后,下次再次訪問頁面不需要再次登錄
- 實現的原理是,在登錄成功后回返回給前端一個token,并存放在一張持久層表中或則內存中,前端存放在Cookie中,下次登錄只要攜帶Cookie,security就直接通過存儲的token比對,不需要重新認證
- 如果指定了數據源,就存放在持久層,如果沒有指定則存放在內存中
- token的過期時間是可以設置的
- 實現步驟:
- 開啟記住我功能
- 如果指定數據源則存放在數據庫中,如果沒有指定則存放在內存中
- 頁面請求時候要傳入一個參數
<beans:beans xmlns="http://www.springframework.org/schema/security"xmlns:beans="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><http auto-config="true"><intercept-url pattern="/login.jsp" access="permitAll()"/><intercept-url pattern="/**" access="hasAnyRole('ROLE_USER')" /><!--指定登錄頁面或登錄成功頁面等,都在這個標簽中可以指定--><form-login login-page="/login.jsp" login-processing-url="/login" authentication-success-forward-url="/home.jsp"/><!-- 錯誤頁面--><access-denied-handler error-page="/error.jsp"/><!--關閉CSRF認證--><csrf disabled="true"/><!--開啟remember功能 token-validity-seconds表示過期時間,單位秒;remember-me-parameter="remember-me"表示傳入的參數名;data-source-ref="dataSource"表示指定的數據源--><remember-metoken-validity-seconds="60"remember-me-parameter="remember-me"data-source-ref="dataSource"/></http><authentication-manager><!--指定認證的類--><authentication-provider user-service-ref="userServiceImpl"><!--給security指定加密的方式--><password-encoder ref="bCryptPasswordEncoder"/></authentication-provider></authentication-manager>
</beans:beans>