SpringCloud系列三:SpringSecurity 安全訪問(配置安全驗證、服務消費端處理、無狀態 Session 配置、定義公共安全配置程序類)

聲明:本文來源於MLDN培訓視頻的課堂筆記,寫在這裏只是爲了方便查閱。java

一、概念:SpringSecurity 安全訪問web

二、具體內容spring

全部的 Rest 服務最終都是暴露在公網上的,也就是說若是你的 Rest 服務屬於一些你本身公司的私人業務,這樣的結果會直接 致使你信息的泄漏,因此對於 Rest 訪問,安全性是首要的因素。安全

2.一、配置安全驗證服務器

若是要想進行安全的驗證處理,那麼首先必定要先在服務的提供方上進行處理。session

一、 【microcloud-provider-dept-8001】修改 pom.xml 配置文件,追加 SpringSecurity 相關依賴包引入:併發

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

若是你如今配置了安全框架,則在啓動時會出現有以下的一個提示信息:app

Using default security password: 75f5d975-0cfc-16e9-b9cc-68fbb0b56465框架

二、 【microcloud-provider-dept-8001】修改 application.yml 配置文件,進行安全的用戶名配置:less

security: basic: enabled: true # 啓用SpringSecurity的安全配置項 user: name: studyjava # 認證用戶名 password: hello # 認證密碼 role: # 受權角色 - USER

隨後在項目之中訪問 Rest 服務接口:http://dept-8001.com:8001/dept/list,此時在訪問的時候會直接詢問用戶要求用戶輸入用戶 名以及密碼。

 

 這個時候有一種更簡化的方法進行內容的輸入:http:/studyjava:hello@dept-8001.com:8001/dept/list;

 2.二、服務消費端處理

 在實際的開發之中,對於 Rest 服務提供者是不可能被用戶直接進行訪問的,因而確定須要有一個 Rest 客戶端(WEB 端、 SpringBoot)進行調用,但是如今 Rest 提供者的服務上有了認證信息,那麼該如何訪問呢?

 public static final String DEPT_GET_URL = "http://studyjava:hello@dept-8001.com:8001/dept/get/";

 若是這個時候在 Rest 客戶端上直接使用用戶名和密碼作加密處理,那麼根本就沒法進行訪問,此時會出現有 401 的錯誤代碼, 由於認證出現了錯誤。之因此沒法訪問,是由於全部的認證的處理操做,應該以頭信息的模式來進行處理。然後要使用Base64進行加密處理後才能夠獲得一個正確的訪問路徑。

 一、 【microcloud-consumer-80】修改 RestConfig 配置類,在這個配置類上追加有新的 Bean 配置項HttpHeaders 

package cn.study.microcloud.config; import java.nio.charset.Charset; import java.util.Base64; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.web.client.RestTemplate; @Configuration public class RestConfig {  @Bean public HttpHeaders getHeaders() { // 要進行一個Http頭信息配置 HttpHeaders headers = new HttpHeaders(); // 定義一個HTTP的頭信息 String auth = "studyjava:hello"; // 認證的原始信息 byte[] encodedAuth = Base64.getEncoder() .encode(auth.getBytes(Charset.forName("US-ASCII"))); // 進行一個加密的處理 // 在進行受權的頭信息內容配置的時候加密的信息必定要與「Basic」之間有一個空格 String authHeader = "Basic " + new String(encodedAuth); headers.set("Authorization", authHeader); return headers; } @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } }

 二、 【microcloud-consumer-80】修改 ConsumerDeptController 配置類,在進行 Rest 訪問的時候設置好這個頭部的信息

package cn.study.microcloud.controller; import java.util.List; import javax.annotation.Resource; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import cn.study.vo.Dept; @RestController public class ConsumerDeptController { public static final String DEPT_GET_URL = "http://dept-8001.com:8001/dept/get/"; public static final String DEPT_LIST_URL = "http://dept-8001.com:8001/dept/list/"; public static final String DEPT_ADD_URL = "http://dept-8001.com:8001/dept/add?dname="; @Resource private RestTemplate restTemplate; @Resource private HttpHeaders headers; @RequestMapping(value = "/consumer/dept/get") public Object getDept(long id) { Dept dept = this.restTemplate .exchange(DEPT_GET_URL + id, HttpMethod.GET, new HttpEntity<Object>(this.headers), Dept.class) .getBody(); return dept; } @SuppressWarnings("unchecked") @RequestMapping(value = "/consumer/dept/list") public Object listDept() { List<Dept> allDepts = this.restTemplate .exchange(DEPT_LIST_URL, HttpMethod.GET, new HttpEntity<Object>(this.headers), List.class) .getBody(); return allDepts; } @RequestMapping(value = "/consumer/dept/add") public Object addDept(Dept dept) throws Exception { Boolean flag = this.restTemplate.exchange(DEPT_ADD_URL, HttpMethod.POST, new HttpEntity<Object>(dept, this.headers), Boolean.class) .getBody(); return flag; } }

 三、無狀態 Session 配置

 經過以前一系列的演示能夠發現整個 Rest 項目中的一個問題所在,全部的 Rest 都是基於 HTTP 協議的一種應用,而在這種應 用上,全部的 WEB 容器通常都會提供有一個 Session 的機制,也就是說每個用戶訪問以後若是該用戶一直鏈接,則認爲該用戶 應該一直被服務器保存狀態,可是微服務有可能同時併發訪問幾十萬人,那麼若是全部的 Session 狀態都被維護着就會出現內存泄漏

 一、 【microcloud-provider-dept-8001】如今修改 Rest 程序類,追加一個取得 session id 的方法:

package cn.study.microcloud.rest; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import cn.study.microcloud.service.IDeptService; import cn.study.vo.Dept; @RestController public class DeptRest { @Resource private IDeptService deptService ; @RequestMapping("/dept/sessionId") public Object id(HttpServletRequest request) { return request.getSession().getId() ; } @RequestMapping(value="/dept/get/{id}",method=RequestMethod.GET) public Object get(@PathVariable("id") long id) { return this.deptService.get(id) ; } @RequestMapping(value="/dept/add",method=RequestMethod.POST) public Object add(@RequestBody Dept dept) { return this.deptService.add(dept) ; } @RequestMapping(value="/dept/list",method=RequestMethod.GET) public Object list() { return this.deptService.list() ; } }

 隨後進行提供者的 Rest 鏈接訪問:http://studyjava:hello@dept-8001.com:8001/dept/sessionId;會發現每訪問一次就會出現不一樣的session id

 二、 在有一些的 SpringCloud 的配置之中,默認是會保存有 Session 狀態的,然後若是用戶有須要則能夠根據「SessionCreationPolicy」 枚舉類進行不一樣的 session 狀態設置,可是從總體的操做來講,session 最好設置爲無狀態。

 · 如下爲保持 Session 狀態(服務器內存有可能被佔滿):

security: sessions: always

 · 如下爲無狀態的 Session 設置(服務器不保存 Session 狀態,每一次鏈接都是一個新的用戶):

security: sessions: stateless 

 無論你之後的項目或者支持類中是否有設置無狀態的問題,你最好都進行一下設置,不然你的 Rest 服務將受到嚴重的內存困 擾,最嚴重的問題就是內存溢出。

 四、定義公共安全配置程序類

 在進行 Rest 服務開發的時候,爲了保證安全全部的程序裏面都須要進行 Spring-Security 安全認證處理,但是以前所進行的認 證處理都是在 application.yml 配置文件完成的,這樣的配置明顯是很是不合乎邏輯的,由於若是此時你要開發的微服務不少,而且 這些微服務都要求使用統一的用戶名和密碼的時候就很是不方便了。因此如今最簡單的作法是進行統一的設置。

 一、 建立一個 microcloud-security 的 Maven 模塊;

 二、 【microcloud-security】修改 pom.xml 配置文件添加spring-boot-starter-security:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

 三、 【microcloud-security】創建一個統一的安全配置類:

package cn.study.microcloud.config; import javax.annotation.Resource; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Resource public void configGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("studyjava").password("hello") .roles("USER").and().withUser("admin").password("hello") .roles("USER", "ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { // 表示全部的訪問都必須進行認證處理後才能夠正常進行
 http.httpBasic().and().authorizeRequests().anyRequest() .fullyAuthenticated(); // 全部的Rest服務必定要設置爲無狀態,以提高操做性能
 http.sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } }

 四、 【microcloud-provider-dept-8001】修改 pom.xml 配置文件,引入安全配置模塊:

<dependency>
            <groupId>cn.study</groupId>
            <artifactId>microcloud-security</artifactId>
        </dependency>

 五、 【microcloud-provider-dept-8001】刪除掉 application.yml 中與安全有關的配置項(如下內容刪除);

security: sessions: stateless basic: enabled: true # 啓用SpringSecurity的安全配置項 user: name: studyjava # 認證用戶名 password: hello # 認證密碼 role: # 受權角色 - USER

 因爲如今所寫的安全處理類是在程序啓動類的子包之中,應該能夠自動掃描到。

 六、 訪問地址:http://mldnjava:hello@dept-8001.com:8001/dept/sessionId

相關文章
相關標籤/搜索