24.Spring-Boot-Actuator與Spring-Security整合應用


      文章是指,在生產環境不是每一個用戶都可以查看監控springboot應用的運行情況,通過整合spring security配置指定用戶訪問Actuator。

     Spring Boot包含了一些額外的特性,可以幫助您在應用程序在上生產時監控和管理應用程序。您可以選擇使用HTTP管理監視您的應用程序。端點,帶有JMX,甚至是遠程shell (SSH或Telnet)。審計、健康和度量收集。可以自動應用到您的應用程序中。

       Actuator是Spring Boot提供的對應用系統的自省和監控的集成功能,可以查看應用配置的詳細信息,例如自動化配置信息、創建的Spring beans以及一些環境屬性等。

Actuator的定義:

官方文檔:

 

An actuator is a manufacturing term, referring to a mechanical device for moving or controlling something. Actuators can generate a large amount of motion from a small change.

翻譯后:

執行器是制造術語,指移動或控制某物的機械裝置。執行器可以從一個小的變化產生大量的運動。

增加Actuator到你的maven工程中:

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

</dependencies>

在Spring MVC應用程序,Spring Boot Actuator 將自動配置所有啟用的端點通過HTTP公開。默認的約定是使用端點的id作為URL路徑。默認情況下,所有敏感的HTTP端點都是安全的,只有具有執行器角色的用戶可以訪問它們。具體Id介紹可參考官方文檔。

如果你在防火牆后面部署應用程序,你可能更喜歡所有的Actuator。可以在不需要身份驗證的情況下訪問端點。

在application.properties中設置

 

management.security.enabled=false  這樣所有的用戶都可以用Actuator。

默認情況下,Actuator端點暴露在服務於常規HTTP的同一個端口上,即就是和你的應用端口是一致的。

如果你的應用程序是公開部署的,你可能希望添加“Spring Security”來處理用戶身份驗證。當“Spring Security”被添加時,默認的“basic”身份驗證將被使用。

具體配置過程如下:

1.配置application.properties

#默認是沒有權限控制的,
#以下配置權限認證,只有當用戶名是admin且密碼為123456,且擁有SUPERADMIN角色是才能訪問
#默認角色為ACTUATOR
#對於密碼,生產上可以配置密文
management.security.enabled=true
security.user.name=admin
security.user.password=123456 
management.security.roles=SUPERADMIN

2.增加SecurityConfig.java類,配置spring-security

package com.niugang.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration // 里面已經包含了@Component 所以不用再上下文中在引入入了
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// spring自帶的
@Autowired
private UserDetailsService userDetailsService;


/**
* configure(HttpSecurity)方法定義了哪些URL路徑應該被保護
*/
@Override

protected void configure(HttpSecurity http) throws Exception {

                                 http.authorizeRequests()// 該方法所返回的對象的方法來配置請求級別的安全細節
.antMatchers("/login").permitAll()// 登錄頁面不攔截
.antMatchers(HttpMethod.POST, "/checkLogin").permitAll().anyRequest().authenticated()// 對於登錄路徑不進行攔截
.and().formLogin()// 配置登錄頁面
.loginPage("/login")// 登錄頁面的訪問路徑;
.loginProcessingUrl("/checkLogin")// 登錄頁面下表單提交的路徑
.failureUrl("/login?paramserror=true")// 登錄失敗后跳轉的路徑,為了給客戶端提示
.defaultSuccessUrl("/index")// 登錄成功后默認跳轉的路徑;
.and().logout()// 用戶退出操作
.logoutUrl("/logout")// 用戶退出所訪問的路徑,需要使用Post方式
.permitAll().logoutSuccessUrl("/login?logout=true")// 退出成功所訪問的路徑
.and().csrf().disable();

}

/**
* 忽略靜態資源
*/


@Override
public void configure(WebSecurity web) throws Exception {
/*
* 在springboot中忽略靜態文件路徑,直接寫靜態文件的文件夾
* springboot默認有靜態文件的放置路徑,如果應用spring security,配置忽略路徑
* 不應該從springboot默認的靜態文件開始
* 如:在本項目中,所有的js和css都放在static下,如果配置忽略路徑,則不能以static開始

* 配置成web.ignoring().antMatchers("/static/*");這樣是不起作用的,如果忽略靜態資源,頁面樣式可能無法加載

*/

web.ignoring().antMatchers("/themes/**","/script/**");
}

        /**
* 配置自定義用戶服務
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
// .passwordEncoder(passwordEncoder());
}
/**
* 密碼加密
*/
/*
* @Bean public BCryptPasswordEncoder passwordEncoder() { return new
* BCryptPasswordEncoder(); }
*/
}

3.添加UserDetailsServiceImpl.java,用於登錄時進行數據庫認證

package com.niugang.service;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.niugang.bean.UserQuery;
import com.niugang.entity.User;
import com.niugang.exception.CheckException;
/**
 * 授權認證業務類
 * 
 * @author niugang UserDetailsService spring security包里面的
 * 重寫loadUserByUsername方法
 *
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

       //UserService自定義的,從數據查詢信息
@Resource
private UserService userService;


public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserQuery user = new UserQuery();
user.setName(username);
// 查詢用戶是否存在
List<User> queryList = userService.queryListByPage(user);
if (queryList != null & queryList.size() == 1) {
// 查詢用戶擁有的角色
List<GrantedAuthority> list = new ArrayList<GrantedAuthority>();
//如果是admin用戶登錄,授予SUPERADMIN權限
if(username.equals("admin")){
list.add(new SimpleGrantedAuthority("SUPERADMIN")); 
}

org.springframework.security.core.userdetails.User authUser = new org.springframework.security.core.userdetails.User(
queryList.get(0).getName(), queryList.get(0).getPassword(), list);


return authUser;
}
return null;

}
}

3.controller中添加代碼,用戶接受登錄參數,調用認證服務

@Autowired(required=true)
private UserDetailsService userDetailsService;

         /**
* 跳轉到登錄頁面
* 
* @param map
* @return
*/
  @RequestMapping(value = "/login", method = RequestMethod.GET)
   public String toLogin(ModelMap map,String paramserror ) {
if(paramserror!=null){
map.put("errorMessage", "用戶名或密碼錯誤");//認證失敗,客戶端返回提示信息
}
      return "view/login";
}

  @RequestMapping(value = "/checkLogin", method = RequestMethod.POST)
public void  checkLogin(String username,String password) {
userDetailsService.loadUserByUsername(username);
}
 4.登錄頁面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link href="themes/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript" src="script/jquery.min.js"></script>
<!--layer彈出框-->
<link rel="stylesheet" href="script/layer/mobile/need/layer.css">
<script type="text/javascript" src="script/layer/layer.js"></script>
</head>
<!-- -->
<style>
form {
width: 60%;
margin: 0 auto;
}
</style>
<body>
<form action="checkLogin" method='post'>
<h2  style="text-align:center">spring boot 
         </h2>
<div class="form-group">
<label for="name">姓名</label> <input type="text" class="form-control"
name="username" placeholder="姓名">
</div>
<div class="form-group">
<label for="password">密碼</label> <input type="password"
class="form-control" name="password" placeholder="密碼">
</div>
<button type="submit" id="btn_save"
class="btn btn-primary form-control">保存</button>
</form>
<script type="text/javascript">
   <#if errorMessage??> 
layer.msg('${errorMessage}', {icon: 4,time:1000,anim: 6});
   
   </#if>

</script>
</body>

5.運行項目

 

登錄頁面

登錄認證失敗提示

通過非admin用戶登錄,成功頁面

 

然后在地址欄輸入ACTUATOR 端點,提示訪問拒絕,必須擁有SUPERADMIN角色權限

admin用戶登錄,訪問http://localhost:8080/myweb/mappings

訪問http://localhost:8080/myweb/metrics

 

 微信公眾號

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM