1. maven依賴(在ssm依賴的基礎上添加)
<properties>
<spring.security.version>5.0.2.RELEASE</spring.security.version>
</properties>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
2.配置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" xmlns:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="cn.msg.service.impl.UserServiceImpl"/>
<!-- 登錄頁面和錯誤頁面不攔截-->
<security:http pattern="/login.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>
<!-- 配置攔截的規則
auto-config="使用自帶的頁面"
use-expressions="是否使用spel表達式",如果使用表達式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="true">
<!-- 配置攔截的請求地址,任何請求地址都必須有ROLE_USER或ROLE_ADMIN的權限當然這個是自己定義的-->
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
<!--
指定安全框架使用的頁面若是不指定會使用security默認登入頁面 此處指定了就要創建這些頁面
login-page:指定登錄頁面
login-processing-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="/login.jsp"
></security:form-login>
<!-- 關閉跨站請求僞造-->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
<!-- 配置認證信息:認證管理器-->
<security:authentication-manager>
<!-- 認證信息的提供者:關聯用戶服務對象,提供賬號和密碼 userService爲UserDetailsService的實現類 -->
<security:authentication-provider user-service-ref="userService">
<!-- 用戶的服務對象-->
<!-- <security:user-service> -->
<!--
用戶信息:臨時賬號和密碼
{noop}:不使用加密
authorities:指定用戶的認證角色
-->
<!-- <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/> -->
<!-- </security:user-service> -->
<!--引用加密工具-->
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<!-- 配置加密工具類-->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
<!-- aop的自動代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<!--配置開啓security的註解支持-->
<security:global-method-security secured-annotations="enabled"/>
</beans>
3.在web.xml中加載security.xml
在web.xml中編寫
<!-- 加載spring.xml security.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml ,classpath:security.xml</param-value>
</context-param>
<!--配置委派代理過濾器: filter-name必須是:springSecurityFilterChain -->
<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>
4.編寫userService接口 此接口要繼承UserDetailsService接口
public interface UserService extends UserDetailsService {
}
5.編寫userService接口的實現類
因爲userService接口繼承了UserDetailsService接口所以UserServiceImpl也實現了UserDetailsService
@Transactional
public class UserServiceImpl implements UserService {
//usermapper我就不再編寫演示了,只需直到他有一個方法login(String username)
//通過username獲取用戶信息,用戶信息包含了用戶所擁有的權限角色
@Autowired
private UserMapper userMapper;
//此爲密碼加密實用類在security.xml配置過了可向上翻看
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 登入
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//1. 根據用戶名查詢一個 sysUser 對象
SysUser sysUser = userMapper.login(username);
if(sysUser!=null) {//若是對象存在
//授權集合
Collection<GrantedAuthority> authorities = new ArrayList<>();
//TODO 從sysUser中獲取到 查詢出來的 所有角色
for(SysRole role:sysUser.getRoleList()){
//此字符傳拼接要與security.xml配置的權限名要對應
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+role.getRoleName());
authorities.add(authority);
}
//若是不需要權限配置可將上for循環註釋然後解鎖下面兩行代碼
// GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_ADMIN");
// authorities.add(authority);
//參數1: 用戶名 ; 參數2: 密碼 (他們都來源於數據庫)
//參數3: 授權集合
User user = new User(sysUser.getUsername(),sysUser.getPassword(), authorities);
return user;
}
return null;
}
}
6.前端防護
由上文可知此實例是有權限判斷的可以根據不同用戶所持有的權限角色展示不同的功能,security提供了<security:authorize access="hasRole('ROLE_ADMIN')">....</security:authorize>
標籤可利用此標籤對前端頁面顯示進行控制,上述標籤的意思爲:只有擁有‘ROLE_ADMIN’權限的用戶登入時纔會顯示標籤中的內容,使用標籤前不要忘了聲明<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
7.@Secured({""})註解 後臺防護
防止沒有權限的用戶登入後使用地址欄進行惡意訪問此用戶沒有的權限
使用方式