Spring Security介紹:
Spring Security 的前身是 Acegi Security ,是 Spring 項目組中用來提供安全認證服務的框架。
(https://projects.spring.io/spring-security/) Spring Security 為基于J2EE企業應用軟件提供了全面安全服務。特別
是使用領先的J2EE解決方案-Spring框架開發的企業軟件項目。人們使用Spring Security有很多種原因,不過通常吸
引他們的是在J2EE Servlet規范或EJB規范中找不到典型企業應用場景的解決方案。 特別要指出的是他們不能再
WAR 或 EAR 級別進行移植。這樣,如果你更換服務器環境,就要,在新的目標環境進行大量的工作,對你的應用
系統進行重新配 置安全。使用Spring Security 解決了這些問題,也為你提供很多有用的,完全可以指定的其他安
全特性。 安全包括兩個主要操作。
<dependencies><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-web</artifactId><version>5.0.1.RELEASE</version></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-config</artifactId><version>5.0.1.RELEASE</version></dependency>
</dependencies>
<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-security.xml</param-value>
</context-param>
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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>
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security.xsd"><!-- 配置不攔截的資源 --><security:http pattern="/login.jsp" security="none"/><security:http pattern="/failer.jsp" security="none"/><security:http pattern="/css/**" security="none"/><security:http pattern="/img/**" security="none"/><security:http pattern="/plugins/**" security="none"/><!--配置具體的規則auto-config="true" 不用自己編寫登錄的頁面,框架提供默認登錄頁面use-expressions="false" 是否使用SPEL表達式(沒學習過)--><security:http auto-config="true" use-expressions="false"><!-- 配置具體的攔截的規則 pattern="請求路徑的規則" access="訪問系統的人,必須有ROLE_USER的角色" --><security:intercept-url pattern="/**" access="ROLE_USER,ROLE_ADMIN"/><!-- 定義跳轉的具體的頁面 --><security:form-loginlogin-page="/login.jsp"login-processing-url="/login.do"default-target-url="/index.jsp"authentication-failure-url="/failer.jsp"authentication-success-forward-url="/pages/main.jsp"/><!-- 關閉跨域請求 --><security:csrf disabled="true"/><!-- 退出 --><security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp" /></security:http><!-- 切換成數據庫中的用戶名和密碼 --><security:authentication-manager><security:authentication-provider user-service-ref="userService"><!-- 配置加密的方式--><security:password-encoder ref="passwordEncoder"/></security:authentication-provider></security:authentication-manager><!-- 配置加密類 --><bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/><!-- 提供了入門的方式,在內存中存入用戶名和密碼<security:authentication-manager><security:authentication-provider><security:user-service><security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/></security:user-service></security:authentication-provider></security:authentication-manager>-->
</beans>
在Spring Security中如果想要使用數據進行認證操作,有很多種操作方式,這里我們介紹使用UserDetails、UserDetailsService來完成操作。
public interface UserDetails extends Serializable {Collection<? extends GrantedAuthority> getAuthorities();String getPassword();String getUsername();boolean isAccountNonExpired();boolean isAccountNonLocked();boolean isCredentialsNonExpired();boolean isEnabled();
}
UserDetails是一個接口,我們可以認為UserDetails作用是于封裝當前進行認證的用戶信息,但由于其是一個接口,所以我們可以對其進行實現,也可以使用Spring Security提供的一個UserDetails的實現類User
來完成操作
以下是User類的部分代碼
public class User implements UserDetails, CredentialsContainer {private String password;private final String username;private final Set<GrantedAuthority> authorities;private final boolean accountNonExpired; //帳戶是否過期private final boolean accountNonLocked; //帳戶是否鎖定private final boolean credentialsNonExpired; //認證是否過期private final boolean enabled; //帳戶是否可用
}
public interface UserDetailsService {UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
<security:authentication-manager><!--userService為 Service層實現類的Bean名稱 --><security:authentication-provider user-service-ref="userService"><!-- 配置加密的方式<security:password-encoder ref="passwordEncoder"/>--></security:authentication-provider>
</security:authentication-manager>
UserDetailsService
public interface UserService extends UserDetailsService{
}//UserServiceImpl代碼
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;UserInfo userInfo = null;@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {try {userInfo = userDao.findByUsername(s);} catch (Exception e) {e.printStackTrace();}User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(),userInfo.getStatus() == 0 ? false : true, true, true, true, getAuthority(userInfo.getRoles()));return user;}private List<SimpleGrantedAuthority> getAuthority(List<Role> roleList) {List<SimpleGrantedAuthority> list = new ArrayList<>();for (Role role : roleList) {list.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));}return list;}@Overridepublic List<UserInfo> findAll() throws Exception {return userDao.findAll();}
}
使用spring security完成用戶退出,非常簡單
<security:logout invalidate-session="true" logout-url="/logout.do" logout-success-
url="/login.jsp" />
<a href="${pageContext.request.contextPath}/logout.do"
class="btn btn-default btn-flat">注銷</a>
SpringBoot入門?在服務器端我們可以通過Spring security提供的注解對方法來進行權限控制。Spring Security在方法的權限控制上支持三種類型的注解,JSR-250注解、@Secured注解和支持表達式的注解,這三種注解默認都是沒有啟用的,需要單獨通過global-method-security
元素的對應屬性進行啟用
開啟注解使用
<!--JSR-250注解-->
<security:global-method-security jsr250-annotations="enabled"/>
<!--@Secured注解-->
<security:global-method-security secured-annotations="enabled"/>
<!--支持表達式的注解-->
<security:global-method-security pre-post-annotations="disabled"/>
使用需要導入依賴
<dependency><groupId>javax.annotation</groupId><artifactId>jsr250-api</artifactId><version>1.0</version>
</dependency>
示例:
@RolesAllowed({“USER”, “ADMIN”}) 該方法只要具有"USER", "ADMIN"任意一種權限就可以訪問。這里可以省略前綴ROLE_,實際的權限可能是ROLE_ADMIN
Spring 框架。示例:
@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")
void changePassword(@P(“userId”) long userId ){ }
這里表示在changePassword方法執行之前,判斷方法參數userId的值是否等于principal中保存的當前用戶的userId,或者當前用戶是否具有ROLE_ADMIN權限,兩種符合其一,就可以訪問該方法。
示例:
@PostAuthorize
User getUser(“returnObject.userId == authentication.principal.userId or
hasPermission(returnObject, ‘ADMIN’)”);
Spring Security允許我們在定義URL訪問或方法訪問所應有的權限時使用Spring EL表達式,在定義所需的訪問權限時如果對應的表達式返回結果為true則表示擁有對應的權限,反之則無。Spring Security可用表達式對象的基類是SecurityExpressionRoot,其為我們提供了如下在使用Spring EL表達式對URL或方法進行權限控制時通用的內置表達式。
表達式 | 描述 |
---|---|
hasRole([role]) | 當前用戶是否擁有指定角色。 |
hasAnyRole([role1,role2]) | 多個角色是一個以逗號進行分隔的字符串。如果當前用戶擁有指定角色中的任意一個則返回true。 |
hasAuthority([auth]) | 等同于hasRole |
hasAnyAuthority([auth1,auth2]) | 等同于hasAnyRole |
Principle | 代表當前用戶的principle對象 |
authentication | 直接從SecurityContext獲取的當前Authentication對象 |
permitAll | 總是返回true,表示允許所有的 |
denyAll | 總是返回false,表示拒絕所有的 |
isAnonymous() | 當前用戶是否是一個匿名用戶 |
isRememberMe() | 表示當前用戶是否是通過Remember-Me自動登錄的 |
isAuthenticated() | 表示當前用戶是否已經登錄認證成功了。 |
isFullyAuthenticated() | 如果當前用戶既不是一個匿名用戶,同時又不是通過Remember-Me自動登錄的,則返回true。 |
springboot入門項目?示例:
@Secured(“IS_AUTHENTICATED_ANONYMOUSLY”)
public Account readAccount(Long id);
@Secured(“ROLE_TELLER”)
在jsp頁面中我們可以使用spring security提供的權限標簽來進行權限控制
<dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-taglibs</artifactId><version>version</version>
</dependency>
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
在jsp中我們可以使用以下三種標簽,其中authentication代表的是當前認證對象,可以獲取當前認證對象信息,例如用戶名。其它兩個標簽我們可以用于權限控制
authentication
<security:authentication property="" htmlEscape="" scope="" var=""/>
Spring入門,authorize
authorize是用來判斷普通權限的,通過判斷用戶是否具有對應的權限而控制其所包含內容的顯示
<security:authorize access="" method="" url="" var=""></security:authorize>
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态