- pom.xml中加入springsecurity依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
- 用戶對象實體
@Data
public class ProjectUser implements Serializable, UserDetails {
private static final long serialVersionUID = 4702398324039042010L;
// todo 用戶的其他屬性
private String username;
/**
* 系統級別的用戶角色枚舉,可以修改成1,2,3存儲在db,節省空間
*/
public enum UserRoleEnum {
/**
* 管理員
*/
ROLE_ADMIN("ROLE_ADMIN", "管理員"),
/**
* 普通用戶
*/
ROLE_NORMAL("ROLE_NORMAL", "普通用戶");
private String key;
private String value;
private UserRoleEnum(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
}
}
- 無密碼編碼,如果需要密碼編碼直接在裏面編寫
public class NoPasswordEncoder implements PasswordEncoder {
@Override
public String encode(CharSequence rawPassword) {
return "";
}
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
return true;
}
}
- 用戶服務,公司的郵箱,直接登錄;如果是toc,需要用戶註冊,登錄分開寫
@Service
@Slf4j
public class UserService implements UserDetailsService {
@Autowired
private AuthenticationManager authenticationManager;
/**
* 通過用戶名加載用戶
*
* @param username
* @return
*/
@Override
public UserDetails loadUserByUsername(String username) {
ProjectUser user = null;//根據自己邏輯獲取用戶
if (user == null) {
throw new UsernameNotFoundException("用戶不存在");
}
return user;
}
/**
* 登陸
*
* @param username
* @return
*/
public ProjectUser login(String username, String password) {
// todo 校驗這個用戶,並登陸並授權
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, encoder.encode(password));
//使用SpringSecurity攔截登陸請求 設置認證,爲了其他接口訪問進行用戶驗證
Authentication authentication = authenticationManager.authenticate(upToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
// todo 返回登陸的用戶信息
}
}
- springsecurity的配置
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //post請求之前進行驗證
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(new NoPasswordEncoder());
}
/**
* 如果是前後分離部署的,這個裏面不用寫靜態資源
* 如果是前後端放在一起的,需要把靜態資源忽略驗證
*
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web
.debug(false)
.ignoring()
.antMatchers("/**/*.html","/webjars/**")
.antMatchers("/**/favicon.ico")
.antMatchers("/fonts/**")
.antMatchers("/css/**")
.antMatchers("/img/**")
.antMatchers("/lib/**")
.antMatchers("/scripts/**")
.antMatchers("/static-css/**")
.antMatchers("/static-icons/**")
.antMatchers("/static-img/**")
.antMatchers("/static-mock/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() //禁用csrf
.authorizeRequests().antMatchers(HttpMethod.GET,"/swagger-resources/configuration/ui",
"/swagger-resources/configuration/security",
"/v2/api-docs",
"/swagger-resources").permitAll()
//給api開的所有接口不走springsecurity
.antMatchers(HttpMethod.POST, "/authentication/login",
"/authentication/logout","/authentication/techplatLogin","/api/token","/api/sql/create","/api/sql/update").permitAll()
.antMatchers("/error","/healthCheck").permitAll()
.antMatchers(HttpMethod.GET,"/api/sql/yarnClusterList","/api/sql/flinksqlEngineList","/api/sql/detail","/api/sql/start"
,"/api/sql/getStartTimeLine","/api/sql/stop","/api/sql/delete").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new AuthenticationEntryPoint() {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(new ResultDTO(401, "未登錄")));
}
})
.accessDeniedHandler(new AccessDeniedHandler() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(new ResultDTO(403, "無權限")));
}
})
.and()
.logout()
.logoutUrl("/authentication/logout")
.invalidateHttpSession(true)
.deleteCookies("project-test-sid", "project-sid")
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setStatus(200);
response.setCharacterEncoding("utf-8");
response.setContentType("text/javascript;charset=utf-8");
response.getWriter().print(JSONObject.toJSONString(ResultDTO.success("註銷成功")));
}
})
.permitAll();
}
}
- springsecurity的工具類,包含獲取當前登錄的用戶
public class WebSecurityUtil {
private WebSecurityUtil() {
throw new IllegalStateException("Utility class");
}
/**
* 獲取當前登錄的用戶
*
* @return
*/
public static ProjectUser getUser() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return (ProjectUser) authentication.getPrincipal();
}
}