Spring Security(Spring安全框架)學習筆記(一)簡介、自定義登錄頁面、放過靜態資源
Spring Security(Spring安全框架)學習筆記(二)登錄接口,登錄參數,登錄回調,註銷登錄
Spring Security(Spring安全框架)學習筆記(三)返回json格式數據,適用前後端分離場景
授權操作
1. SecurityConfig.java
package com.hx.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
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.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import java.io.PrintWriter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
// 密碼加密實例
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // 採用不加密方式
}
/**
* 在內存中創建用戶的方法
* 與之前的創建方法不同
* spring Security支持多種方式去創建用戶
* @return
*/
@Override
@Bean
protected UserDetailsService userDetailsService(){
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("whx").password("a").roles("admin").build());
manager.createUser(User.withUsername("hx").password("a").roles("user").build());
return manager;
}
/**
* 權限繼承
* @return
*/
@Bean
RoleHierarchy roleHierarchy(){
RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
hierarchy.setHierarchy("ROLE_admin > ROLE_user"); //設置權限繼承,管理員權限>用戶權限
return hierarchy;
}
/**
* 放過資源
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/js/**", "/css/**", "images/**"); //放過靜態資源下的js,css,img資源
}
/**
* http安全配置
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//authorizeRequests開啓配置
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin") //從上往下依次匹配
.antMatchers("/user/**").hasRole("user")
.anyRequest() //攔截規則:anyRequest所有請求都攔截,必須寫在前邊兩個的後邊
.authenticated()
.and()
.formLogin() //formLogin表單配置
.loginProcessingUrl("/doLogin") //指定登錄請求接口,若不配置則與指定的loginPage相同
//登錄成功的回調
.successHandler((req,resp,authentication) -> { //authentication:存儲用戶信息
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將用戶信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString(authentication.getPrincipal()));
out.flush();
out.close();
})
//登錄失敗的回調
.failureHandler((req,resp,exception) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString(exception.getMessage()));
out.flush();
out.close();
})
.permitAll()
.and()
.logout()
.logoutUrl("/logout") //配置退出登錄地址
.logoutSuccessHandler((req,resp,authentication) -> {
resp.setContentType("application/json;charset=utf-8");
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString("loginout success"));
out.flush();
out.close();
})
.and()
.csrf().disable() //關閉csrf
.exceptionHandling()
.authenticationEntryPoint((req,resp,e) -> {
resp.setContentType("application/json;charset=utf-8");
resp.setStatus(401); //設置響應狀態碼,401
PrintWriter out = resp.getWriter();
//將錯誤信息以json格式返回給前端
out.write(new ObjectMapper().writeValueAsString("unlogin"));
out.flush();
out.close();
});
}
}