SpringScurity的快速入門

什麼是SpringScurity

springScurity是爲基於spring的應用程序提供安全保護的聲明示安全框架,它可以在處理web請求的時候通過過濾器鏈對類和方法進行認證([authentication)和授權(authorization);

SpringScurity的XML配置

1.導入SpringScurity的相關jar包

2.在web.XML裏面配置如下代碼:

  <!-- 配置加載類路徑的配置文件 -->
 <context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath*:applicationContext.xml,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>

3.創建一個springScurity的配置文件

<?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">


<!--配置權限顆粒器-->
<!--@Secured註解支持 : secured-annotations="enabled"-->   
<!--@RolesAllowed註解支持 : jsr250-annotations-->  需要添加jsr250 jar包
<!--開啓全局方法安全控制-->
<security:global-method-security secured-annotations="enabled" jsr250-annotations="enabled" pre-post-annotations="enabled"/>

<!--配置不攔截的資源-->
<security:http pattern="/failer.jsp" security="none"/>
<security:http pattern="/login.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 use-expressions="true">


    <!--配置具體攔截的url,pattern是攔截的url,access是訪問被攔截的url需要的權限-->
    <security:intercept-url pattern="/**" access="hasAnyAuthority('ROLE_USER','ROLE_ADMIN')"/>

    <!--定義跳轉的具體頁面-->
    <!--
    form-login是spring security命名空間配置登錄相關信息的標籤,它包含如下屬性:
    1. login-page 自定義登錄頁url,默認爲/login
    2. login-processing-url 登錄請求攔截的url,也就是form表單提交時指定的action
    3. default-target-url 默認登錄成功後跳轉的url
    4. always-use-default-target 是否總是使用默認的登錄成功後跳轉url
    5. authentication-failure-url 登錄失敗後跳轉的url
    6. username-parameter 用戶名的請求字段 默認爲userName
    7. password-parameter 密碼的請求字段 默認爲password
    8. authentication-success-handler-ref 指向一個AuthenticationSuccessHandler用於處理認證成功的請求,不能和default-target-url還有always-use-default-target同時使用
    9. authentication-success-forward-url 用於authentication-failure-handler-ref
    10. authentication-failure-handler-ref 指向一個AuthenticationFailureHandler用於處理失敗的認證請求
    11. authentication-failure-forward-url 用於authentication-failure-handler-ref
    12. authentication-details-source-ref 指向一個AuthenticationDetailsSource,在認證過濾器中使用
    -->
    <security:form-login
            login-page="/login.jsp"
            login-processing-url="/login.do"
            default-target-url="/pages/main.jsp"
            always-use-default-target="true"
            authentication-failure-url="/failer.jsp"
    />
    <!--關閉跨域請求,不關閉就會攔截所有的訪問,顯示權限不夠-->
    <!--<security:csrf disabled="true"/>-->
    <security:csrf disabled="true"/>

    <!--退出-->
    <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.jsp"/>

</security:http>


<!--切換成數據庫中的用戶名和密碼-->
<security:authentication-manager>
	<!--配置需要加密的service-->	
    <security:authentication-provider user-service-ref="userService">
        <!-- 配置加密的方式 -->
        <security:password-encoder ref="passwordEncoder"/>
    </security:authentication-provider>
</security:authentication-manager>

<!--或者將驗證方式改爲直接認證不查數據庫
 <security:authentication-manager>
	<!--配置service-->
	<security:authentication-provider>	
  		<security:user-service>
  			<security:user username="admin" password="123"  authorities="ROLE_ADMIN"/>
  			<!--如果是springScurity5.0以上的版本
			<security:user username="admin" password="{noop}123"  authorities="ROLE_ADMIN"/>
-->	
  		</security:user-service>
    </security:authentication-provider>
</security:authentication-manager>
這樣就不用寫用戶類和實現類了,賬號和密碼就是自己在user標籤裏面配的,權限一定要是<security:intercept-url pattern="/**" access="hasAnyAuthority('ROLE_USER','ROLE_ADMIN')"/>裏面的任何一個。也不需要配置加密器了
-->


<!--配置密碼加密器,在登陸的時候一定要用密文登陸,如果用明文就需要在密碼前加"{noop}"拼接-->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

</beans>

編寫service類

1.自定義一個service接口實現UserDetailService(該接口是SpringScurity提供的),複寫它的登入方法.原理是當登入頁面輸入賬號密碼的時候,過濾器會獲取用戶在頁面輸入的數據,然後該接口的實現類會通過用戶的賬號去查數據庫,如果數據庫查出的數據和過濾器獲取的數據匹配成功,則會跳轉到自己設置的認證成功頁面在這裏插入圖片描述,並且該用戶擁有相應的權限,就會認證成功,登陸通過。

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.List;

public interface UserService extends UserDetailsService {

@Override
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

2.實現類

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

//將該類加入spring容器管理
@Service("userService")
//開啓註解事務
@Transactional
public class UserServiceImpl implements UserService {

@Autowired
private UserInfoMapper userInfoMapper;

@Autowired
PasswordEncoder passwordEncoder;


@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
	//查詢數據庫將信息封裝到自己的對象類userInfo中
    UserInfo userInfo = userInfoMapper.findUserByUsername(username);
    //獲取用戶的權限列表
    List<SimpleGrantedAuthority> authority = getAuthority(userInfo.getRoles());
    //User是SpringScurity提供的類
    User user = new User(userInfo.getUsername(),userInfo.getPassword(), userInfo.getStatus() != 0,true,true,true,authority);
    //返回數據之後SpringScurity會將數據庫查詢的信息與攔截器中的數據對比
    return user;
	}


public List<SimpleGrantedAuthority> getAuthority(List<Role> roles){
    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
    for (Role role : roles) {
        authorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
    }
   		 return authorities;
	}
}

3.配置完之後,不管訪問哪個路徑,SpringScurity都會判斷該用戶是否登陸,如果沒有登陸,就會跳轉到登陸頁面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章