新版SpringSecurity5.x使用與配置詳解
一、了解SpringSecurity
1.1 什么是Spring Security?
Spring Security 是一個(gè)強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架。它是 Spring 生態(tài)系統(tǒng)的一部分,為基于 Spring 的應(yīng)用提供了全面的安全服務(wù)。Spring Security 的設(shè)計(jì)目標(biāo)是為應(yīng)用的安全需求提供一個(gè)完整的解決方案,同時(shí)保持高度的靈活性和可擴(kuò)展性。
1.2 Spring Security功能
Spring Security 提供的功能包括但不限于:
- 認(rèn)證(Authentication):驗(yàn)證用戶身份,通常需要用戶名和密碼。
- 授權(quán)(Authorization):確定已認(rèn)證的用戶可以訪問(wèn)哪些資源或執(zhí)行哪些操作。
- CSRF 保護(hù):防止跨站請(qǐng)求偽造攻擊。
- 會(huì)話管理:處理用戶的會(huì)話,包括會(huì)話的創(chuàng)建、維護(hù)和銷毀。
- 加密和編碼:提供加密和散列算法的支持。
- OAuth2 和 OpenID Connect 支持:集成 OAuth2 和 OpenID Connect 協(xié)議,實(shí)現(xiàn)第三方認(rèn)證。
- CORS 支持:處理跨域資源共享(Cross-Origin Resource Sharing)請(qǐng)求。
- 安全配置:允許通過(guò) XML 或 Java 配置來(lái)定制安全策略。
1.3 Spring Security原理
Spring Security 的工作原理涉及幾個(gè)關(guān)鍵組件:
- SecurityContext:存儲(chǔ)認(rèn)證信息,如當(dāng)前登錄用戶和他們的權(quán)限。
- AuthenticationManager:負(fù)責(zé)用戶認(rèn)證,通常使用
UserDetailsService來(lái)加載用戶信息。 - AccessDecisionManager:決定用戶是否有權(quán)訪問(wèn)特定資源。
- Filter Chain:一系列的過(guò)濾器處理請(qǐng)求和響應(yīng),例如
UsernamePasswordAuthenticationFilter用于處理用戶名和密碼的提交。

1.4 RABC (Role-Based Access Control)
RABC,即基于角色的訪問(wèn)控制,是一種常見(jiàn)的訪問(wèn)控制機(jī)制,用于管理用戶對(duì)資源的訪問(wèn)權(quán)限。在 RABC 中,權(quán)限不是直接授予用戶,而是授予用戶所屬的角色。每個(gè)用戶可以擁有一個(gè)或多個(gè)角色,而每個(gè)角色則有一組相應(yīng)的權(quán)限。這種機(jī)制簡(jiǎn)化了權(quán)限管理,因?yàn)橹恍韪挠脩舻慕巧涂梢愿淖兯麄兊臋?quán)限集。

二、SpringSecurity簡(jiǎn)單案例
2.1 引入SpringSecurity依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>2.2 創(chuàng)建一個(gè)簡(jiǎn)單的Controller
@RestController
public class HelloController {
@GetMapping("Hello")
public String Hello(){
return "Hello SpringSecurity";
}
}
2.3 運(yùn)行后訪問(wèn)localhost:8080/Hello會(huì)自動(dòng)跳轉(zhuǎn)到localhost:8080/login

這里的用戶密碼都在啟動(dòng)時(shí)候的控制臺(tái)上 (注意:每一次啟動(dòng)密碼都不一樣)

用戶名:user
密碼: b82aa5e5-0a3a-466b-90a8-e94098877823(控制臺(tái)上的一串密碼)
登陸后成功訪問(wèn)

三、SpringSecurity配置
后面的配置都是基于小案例的基礎(chǔ)上實(shí)現(xiàn),請(qǐng)先完成上述的小案例
3.1 自定義用戶與密碼
由于每一次生成密碼都是不固定的,對(duì)調(diào)試并不友好,springSecurity可以通過(guò)在application.yml中進(jìn)行自定義設(shè)置用戶和密碼
spring:
security:
user:
name: alphaMilk
password: 123456輸入用戶名和密碼即可正常登陸并訪問(wèn)資源

3.2 允許匿名訪問(wèn)路徑
在Spring Security框架中,允許某些路徑或資源在未經(jīng)過(guò)身份驗(yàn)證的情況下被訪問(wèn),通常稱為“允許匿名訪問(wèn)”。這種配置對(duì)于公共頁(yè)面、登錄頁(yè)面、注冊(cè)頁(yè)面、API文檔等是非常必要的,因?yàn)檫@些頁(yè)面或資源需要對(duì)所有用戶開(kāi)放,無(wú)論他們是否已經(jīng)登錄。
以下通過(guò)配置類實(shí)現(xiàn),用戶能夠匿名訪問(wèn)login頁(yè)面
// 使用@Configuration標(biāo)記此類為Spring的配置類
@Configuration
// 啟用WebSecurity的自動(dòng)配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {
// 定義一個(gè)名為securityFilterChain的bean,該bean將負(fù)責(zé)構(gòu)建和應(yīng)用安全過(guò)濾器鏈
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置HttpSecurity對(duì)象,定義安全規(guī)則
http
// 授權(quán)HTTP請(qǐng)求,定義哪些URL需要什么類型的訪問(wèn)控制
.authorizeHttpRequests((authz) -> authz
// 允許"/user/login" URL匿名訪問(wèn)
.requestMatchers("/user/login").anonymous()
// 所有其他請(qǐng)求都需要認(rèn)證才能訪問(wèn)
.anyRequest().authenticated())
// 啟用HTTP Basic認(rèn)證,默認(rèn)情況下提供簡(jiǎn)單的用戶名/密碼認(rèn)證
.httpBasic(Customizer.withDefaults());
// 構(gòu)建并返回SecurityFilterChain
return http.build();
}
}創(chuàng)建一個(gè)LoginController類
@RestController
@RequestMapping("user")
public class LoginController {
@GetMapping("/login")
public String Login(){
return "這是登陸資源頁(yè)面";
}
}

重啟系統(tǒng)后直接訪問(wèn),不需要登陸即可獲取資源.
3.3 數(shù)據(jù)庫(kù)實(shí)現(xiàn)登陸校驗(yàn)
通過(guò)自己數(shù)據(jù)庫(kù)的用戶和密碼,實(shí)現(xiàn)登陸。將之前的自定義用戶密碼(application.yml中)都刪除掉,并執(zhí)行以下操作:
用戶表單:
-- 創(chuàng)建一個(gè)包含用戶信息和角色的簡(jiǎn)化表
CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY, -- 用戶ID,自增主鍵
`username` VARCHAR(255) NOT NULL UNIQUE, -- 用戶名,唯一且不能為空
`password` VARCHAR(255) NOT NULL, -- 密碼,存儲(chǔ)加密后的密碼
`role` ENUM('ROLE_USER', 'ROLE_ADMIN') NOT NULL, -- 角色,預(yù)定義為'ROLE_USER'或'ROLE_ADMIN'
`enabled` TINYINT(1) NOT NULL DEFAULT 1 -- 用戶狀態(tài),1表示啟用,0表示禁用
);注意:這里的role需要按照ROLE_身份 的方式進(jìn)行存儲(chǔ)以便springsecurity進(jìn)行權(quán)限訪問(wèn)控制
插入案例數(shù)據(jù) :
-- 插入示例用戶數(shù)據(jù)
INSERT INTO `users` (`username`, `password`, `role`, `enabled`)
VALUES
('user1', '123456', 'ROLE_USER', 1),
('admin1', '123456', 'ROLE_ADMIN', 1),
('disabledUser', '123456', 'ROLE_USER', 0);
引入依賴:
<!-- 數(shù)據(jù)庫(kù)依賴-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>配置數(shù)據(jù)源:
spring:
datasource:
url: jdbc:mysql://localhost:3306/ap_security?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver創(chuàng)建User實(shí)體與mapper并加上啟動(dòng)注釋
User實(shí)體
@TableName(value ="users")
@Data
public class Users implements Serializable {
/**
*
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
*
*/
private String username;
/**
*
*/
private String password;
/**
*
*/
private Object role;
/**
*
*/
private Integer enabled;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
Users other = (Users) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getUsername() == null ? other.getUsername() == null : this.getUsername().equals(other.getUsername()))
&& (this.getPassword() == null ? other.getPassword() == null : this.getPassword().equals(other.getPassword()))
&& (this.getRole() == null ? other.getRole() == null : this.getRole().equals(other.getRole()))
&& (this.getEnabled() == null ? other.getEnabled() == null : this.getEnabled().equals(other.getEnabled()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getUsername() == null) ? 0 : getUsername().hashCode());
result = prime * result + ((getPassword() == null) ? 0 : getPassword().hashCode());
result = prime * result + ((getRole() == null) ? 0 : getRole().hashCode());
result = prime * result + ((getEnabled() == null) ? 0 : getEnabled().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", username=").append(username);
sb.append(", password=").append(password);
sb.append(", role=").append(role);
sb.append(", enabled=").append(enabled);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
}UserMapper
public interface UsersMapper extends BaseMapper<Users> {
}
@MapperScan
@SpringBootApplication
@MapperScan("com.example.mysecurity.mapper")
public class MySecurityApplication {
public static void main(String[] args) {
SpringApplication.run(MySecurityApplication.class, args);
}
}
測(cè)試mybatisPlus是否配置正確
@SpringBootTest
class MySecurityApplicationTests {
@Autowired
private UsersMapper usersMapper;
@Test
void contextLoads() {
List<Users> users = usersMapper.selectList(null);
System.out.println(users);
}
}
通過(guò)后,即可開(kāi)始實(shí)現(xiàn)通過(guò)自己數(shù)據(jù)庫(kù)進(jìn)行登陸功能:
先創(chuàng)建返回的驗(yàn)證類
LoginUser 實(shí)現(xiàn) UserDetails
@Data
@NoArgsConstructor
@AllArgsConstructor
public class LoginUser implements UserDetails {
private Users user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}登陸實(shí)現(xiàn)類
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UsersMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//根據(jù)用戶名查詢用戶信息
LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Users::getUsername,username);
Users user = userMapper.selectOne(wrapper);
//如果查詢不到數(shù)據(jù)就通過(guò)拋出異常來(lái)給出提示
if(Objects.isNull(user)){
throw new RuntimeException("用戶名或密碼錯(cuò)誤");
}
Collection<? extends GrantedAuthority> authorities = Collections.singletonList(new SimpleGrantedAuthority(user.getRole()));
//封裝成UserDetails對(duì)象返回
return new LoginUser(user,authorities);
}
}由于在Spring Boot 2.3及更高版本中,Spring Security默認(rèn)不再提供任何內(nèi)置的PasswordEncoder。這意味著如果在配置中直接使用明文密碼或沒(méi)有正確配置PasswordEncoder,你將看到這個(gè)異常。這里暫時(shí)先使用明文加密。后面將一步步完善加密功能.
在SecurityConfig中加入配置
@Configuration
// 啟用WebSecurity的自動(dòng)配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {
// 設(shè)置密碼加密為明文加密
@Bean
public org.springframework.security.crypto.password.PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
// 定義一個(gè)名為securityFilterChain的bean,該bean將負(fù)責(zé)構(gòu)建和應(yīng)用安全過(guò)濾器鏈
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置HttpSecurity對(duì)象,定義安全規(guī)則
http
// 授權(quán)HTTP請(qǐng)求,定義哪些URL需要什么類型的訪問(wèn)控制
.authorizeHttpRequests((authz) -> authz
// 允許"/user/login" URL匿名訪問(wèn)
.requestMatchers("/user/login").anonymous()
// 所有其他請(qǐng)求都需要認(rèn)證才能訪問(wèn)
.anyRequest().authenticated())
// 啟用HTTP Basic認(rèn)證,默認(rèn)情況下提供簡(jiǎn)單的用戶名/密碼認(rèn)證
.httpBasic(Customizer.withDefaults());
// 構(gòu)建并返回SecurityFilterChain
return http.build();
}
}再次訪問(wèn)localhost:8080/Hello后彈出登陸框:
輸入任意的用戶與密碼即可正常訪問(wèn)

3.4 實(shí)現(xiàn)角色權(quán)限訪問(wèn)
在Controller中定義一個(gè)Admin資源類,只有admin用戶才能進(jìn)行訪問(wèn)
@RequestMapping("admin")
@RestController
@Slf4j
public class AdminController {
@GetMapping("resourse")
public String AdminRole(){
return "這是只有管理員用戶才能訪問(wèn)的資源";
}
}
在設(shè)置中進(jìn)行配置
@Configuration
// 啟用WebSecurity的自動(dòng)配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {
// 設(shè)置密碼加密為明文加密
@Bean
public org.springframework.security.crypto.password.PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
// 定義一個(gè)名為securityFilterChain的bean,該bean將負(fù)責(zé)構(gòu)建和應(yīng)用安全過(guò)濾器鏈
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置HttpSecurity對(duì)象,定義安全規(guī)則
http
// 授權(quán)HTTP請(qǐng)求,定義哪些URL需要什么類型的訪問(wèn)控制
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用戶才能進(jìn)行訪問(wèn)
.requestMatchers("/admin/**").hasRole("ADMIN")
// 所有其他請(qǐng)求都需要認(rèn)證才能訪問(wèn)
.anyRequest().authenticated())
// 啟用HTTP Basic認(rèn)證,默認(rèn)情況下提供簡(jiǎn)單的用戶名/密碼認(rèn)證
.httpBasic(Customizer.withDefaults());
// 構(gòu)建并返回SecurityFilterChain
return http.build();
}
}重啟服務(wù)器后分別用兩種身份進(jìn)行訪問(wèn)
用戶訪問(wèn):

管理員訪問(wèn):

3.5 對(duì)密碼進(jìn)行B加密
config中進(jìn)行配置BCrypt
@Configuration
// 啟用WebSecurity的自動(dòng)配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
private UserDetailsServiceImpl userDetailsService;
// 設(shè)置密碼加密為B加密
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
// 定義一個(gè)名為securityFilterChain的bean,該bean將負(fù)責(zé)構(gòu)建和應(yīng)用安全過(guò)濾器鏈
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置HttpSecurity對(duì)象,定義安全規(guī)則
http
// 授權(quán)HTTP請(qǐng)求,定義哪些URL需要什么類型的訪問(wèn)控制
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用戶才能進(jìn)行訪問(wèn)
.requestMatchers("/admin/**").hasRole("ADMIN")
// 所有其他請(qǐng)求都需要認(rèn)證才能訪問(wèn)
.anyRequest().authenticated())
// 啟用HTTP Basic認(rèn)證,默認(rèn)情況下提供簡(jiǎn)單的用戶名/密碼認(rèn)證
.httpBasic(Customizer.withDefaults());
// 構(gòu)建并返回SecurityFilterChain
return http.build();
}
}由于數(shù)據(jù)庫(kù)中都是明文的密碼,所以這里可以通過(guò)創(chuàng)建一個(gè)SpringbootTest類,將所有用戶的密碼改為B加密后的數(shù)據(jù).
@Test
public void testUpdateAllPasswords() {
// 創(chuàng)建一個(gè)BCryptPasswordEncoder實(shí)例
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// 更新所有用戶的密碼為加密后的"123456"
String encodedPassword = encoder.encode("123456");
// 構(gòu)造更新條件
LambdaUpdateWrapper<Users> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(Users::getPassword, encodedPassword);
// 執(zhí)行更新操作
boolean result = usersMapper.update(null, updateWrapper) > 0;
if (result) {
System.out.println("所有用戶的密碼更新成功!");
} else {
System.out.println("密碼更新失敗!");
}
}

配置好后,重新進(jìn)行登陸查看輸入對(duì)應(yīng)的admin1和123456

3.6 結(jié)合Jwt實(shí)現(xiàn)多重校驗(yàn)
Spring Security 和 JSON Web Tokens (JWT) 可以協(xié)同工作來(lái)提供更靈活和安全的身份驗(yàn)證和授權(quán)機(jī)制。盡管 Spring Security 提供了一套全面的安全框架,但它默認(rèn)使用基于會(huì)話的認(rèn)證機(jī)制,這意味著服務(wù)器維護(hù)著與客戶端的活動(dòng)會(huì)話狀態(tài)。而JWT提供了一種無(wú)狀態(tài)的認(rèn)證方式,這意味著每個(gè)請(qǐng)求都包含完整的認(rèn)證信息,無(wú)需服務(wù)器保存會(huì)話狀態(tài)。
pom文件中引入jwt所需要的依賴
<!-- JWT依賴-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>Jwt資源類:
@Component
@ConfigurationProperties(prefix = "jwt")
@Data
public class JwtProperties {
private String SecretKey;
private long Ttl;
private String TokenName;
}
Jwt yml配置:
jwt: secret-key: Alphamilk token-name: Authorization ttl: 10800000
實(shí)現(xiàn)Jwt的工具類
@Component
public class JwtUtil {
@Autowired
private JwtProperties jwtProperties;
public String createJWT(Map<String, Object> claims, long ttlMillis) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long expMillis = System.currentTimeMillis() + ttlMillis;
Date exp = new Date(expMillis);
return Jwts.builder()
.setClaims(claims)
.signWith(signatureAlgorithm, jwtProperties.getSecretKey().getBytes(StandardCharsets.UTF_8))
.setExpiration(exp)
.compact();
}
public Claims parseJWT(String token) {
return Jwts.parser()
.setSigningKey(jwtProperties.getSecretKey().getBytes(StandardCharsets.UTF_8))
.parseClaimsJws(token)
.getBody();
}
public boolean isTokenValid(String token, UserDetails userDetails) {
final String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
private String getUsernameFromToken(String token) {
Claims claims = parseJWT(token);
return (String) claims.getSubject();
}
private boolean isTokenExpired(String token) {
try {
final Date expiration = parseJWT(token).getExpiration();
return expiration.before(new Date());
} catch (ExpiredJwtException e) {
return true;
}
}
}Jwt的校驗(yàn)Filter
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private JwtProperties jwtProperties;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String token = request.getHeader(jwtProperties.getTokenName());
if (token != null) {
try {
Claims claims = jwtUtil.parseJWT(token);
String username = (String) claims.get("userName");
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.isTokenValid(token, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
} catch (ExpiredJwtException ex) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Token has expired.");
} catch (JwtException ex) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid token.");
}
}else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "No token provided.");
}
filterChain.doFilter(request, response);
}
}將jwt校驗(yàn)規(guī)則加入到Spring的Filter中進(jìn)行校驗(yàn)
@Configuration
// 啟用WebSecurity的自動(dòng)配置,以便Spring Security可以管理Web安全
@EnableWebSecurity
public class SecurityConfiguration {
@Autowired
private JwtFilter jwtFilter;
@Autowired
private UserDetailsServiceImpl userDetailsService;
// 設(shè)置密碼加密為B加密
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
// 定義一個(gè)名為securityFilterChain的bean,該bean將負(fù)責(zé)構(gòu)建和應(yīng)用安全過(guò)濾器鏈
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// 配置HttpSecurity對(duì)象,定義安全規(guī)則
http
// 授權(quán)HTTP請(qǐng)求,定義哪些URL需要什么類型的訪問(wèn)控制
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/user/login").anonymous()
// 需要有Admin身份的用戶才能進(jìn)行訪問(wèn)
.requestMatchers("/admin/**").hasRole("ADMIN")
// 所有其他請(qǐng)求都需要認(rèn)證才能訪問(wèn)
.anyRequest().authenticated())
// 啟用HTTP Basic認(rèn)證,默認(rèn)情況下提供簡(jiǎn)單的用戶名/密碼認(rèn)證
.httpBasic(Customizer.withDefaults());
// 加入jwtFIlter
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
// 構(gòu)建并返回SecurityFilterChain
return http.build();
}
}到此這篇關(guān)于新版SpringSecurity5.x使用與配置詳解的文章就介紹到這了,更多相關(guān)SpringSecurity5.x使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springsecurity實(shí)現(xiàn)攔截器的使用示例
- SpringSecurity整合JWT的使用示例
- SpringSecurity攔截器鏈的使用詳解
- SpringSecurity實(shí)現(xiàn)權(quán)限認(rèn)證與授權(quán)的使用示例
- SpringSecurity默認(rèn)登錄頁(yè)的使用示例教程
- 使用SpringSecurity+defaultSuccessUrl不跳轉(zhuǎn)指定頁(yè)面的問(wèn)題解決方法
- SpringSecurity入門(mén)使用教程
- springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目)
- Spring Security 使用 OncePerRequestFilter 過(guò)濾器校驗(yàn)登錄過(guò)期、請(qǐng)求日志等操作
- Spring Security使用多種加密方式進(jìn)行密碼校驗(yàn)的代碼示例
相關(guān)文章
IDEA 去除 mybatis.xml 文件黃色警告的圖文教程
這篇文章主要介紹了IDEA 去除 mybatis.xml 文件黃色警告的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Java使用Apache compress實(shí)現(xiàn)文件夾壓縮成Zip包
Apache common提供了很多實(shí)用的工具包,這篇文章主要來(lái)和大家介紹一下Java如何使用Apache compress包實(shí)現(xiàn)文件夾壓縮成Zip包,希望對(duì)大家有所幫助2024-01-01
idea啟動(dòng)與jar包啟動(dòng)中使用resource資源文件路徑的問(wèn)題
這篇文章主要介紹了idea啟動(dòng)與jar包啟動(dòng)中使用resource資源文件路徑的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
java中如何實(shí)現(xiàn) zip rar 7z 壓縮包解壓
這篇文章主要介紹了java中如何實(shí)現(xiàn) zip rar 7z 壓縮包解壓?jiǎn)栴},具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Mybatis3中方法返回生成的主鍵:XML,@SelectKey,@Options詳解
這篇文章主要介紹了Mybatis3中方法返回生成的主鍵:XML,@SelectKey,@Options,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
SpringBoot下實(shí)現(xiàn)session保持方式
這篇文章主要介紹了SpringBoot下實(shí)現(xiàn)session保持方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot+mail 輕松實(shí)現(xiàn)各類郵件自動(dòng)推送
在實(shí)際的項(xiàng)目開(kāi)發(fā)過(guò)程中,經(jīng)常需要用到郵件通知功能,例如,通過(guò)郵箱注冊(cè),郵箱找回密碼,郵箱推送報(bào)表等等,實(shí)際的應(yīng)用場(chǎng)景非常的多,今天通過(guò)這篇文章,我們一起來(lái)學(xué)習(xí)如何在 Spring Boot 中快速實(shí)現(xiàn)一個(gè)自動(dòng)發(fā)送郵件的功能2024-07-07
Java Swing GridBagLayout網(wǎng)格袋布局的實(shí)現(xiàn)
這篇文章主要介紹了Java Swing GridBagLayout網(wǎng)格袋布局的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
JavaWeb項(xiàng)目音頻資源播放實(shí)現(xiàn)方法詳解
這篇文章主要介紹了JavaWeb項(xiàng)目音頻資源播放實(shí)現(xiàn)方法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測(cè)------lof算法
這篇文章主要介紹了Java實(shí)現(xiàn) 基于密度的局部離群點(diǎn)檢測(cè)------lof算法,本文通過(guò)算法概述,算法Java源碼,測(cè)試結(jié)果等方面一一進(jìn)行說(shuō)明,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07

