最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Security前后端分離接入保姆級教程

 更新時間:2025年11月26日 09:02:39   作者:佛祖讓我來巡山  
文章詳細(xì)介紹了如何基于角色權(quán)限模型與數(shù)據(jù)權(quán)限控制,使用SpringSecurity實現(xiàn)一個小型攝影作品管理系統(tǒng)的前后端分離認(rèn)證鑒權(quán)流程,從基礎(chǔ)接入到權(quán)限擴(kuò)展和數(shù)據(jù)權(quán)限控制,每一步都提供了自定義類、代碼、注釋和邏輯說明,感興趣的朋友跟隨小編一起看看吧

基 于 角 色 權(quán) 限 模 型 與 數(shù) 據(jù) 權(quán) 限 控 制

以 小 明 的 攝 影 作 品 管 理 系 統(tǒng) 為 例 , 從 零 基 礎(chǔ) 搭 建 到 完 整 認(rèn) 證 鑒 權(quán) , 逐 步 演 示 Spring Security 的 接 入 流 程 。 涵 蓋 基 礎(chǔ) 接 入 、 角 色 權(quán) 限 擴(kuò) 展 、 數(shù) 據(jù) 權(quán) 限 控 制 三 大 模 塊 , 每 步 標(biāo) 注 自 定 義 類 與 Spring Security 擴(kuò) 展 點 , 配 代 碼 、 注 釋 和 邏 輯 說 明 。 使 用 MyBatisPlus 作 為 ORM 框 架 。

** 第 一 部 分 : 基 礎(chǔ) 接 入 流 程 — 前 后 端 分 離 認(rèn) 證 鑒 權(quán) **

** 第 一 步 : 環(huán) 境 準(zhǔn) 備 與 依 賴 引 入 **

** 目 的 **

搭 建 Spring Boot 基 礎(chǔ) 項 目 , 引 入 Spring Security 及 前 后 端 分 離 必 需 組 件 , 使 用 MyBatisPlus 替 代 JPA 。

** 操 作 **

  • ** 創(chuàng) 建 Spring Boot 項 目 **
  • 通 過 start.spring.io 創(chuàng) 建 , 選 擇 Maven 、 Java 17+ , 添 加 依 賴 Spring Web 、 Spring Security 、 MyBatis Plus 、 MySQL Driver 、 Lombok 。
  • ** Pom.xml 核 心 依 賴 **
<dependencies>  
    <!-- Spring Web -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
    </dependency>  
    <!-- Spring Security -->  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-security</artifactId>  
    </dependency>  
    <!-- MyBatis Plus -->  
    <dependency>  
        <groupId>com.baomidou</groupId>  
        <artifactId>mybatis-plus-boot-starter</artifactId>  
        <version>3.5.3.1</version>  
    </dependency>  
    <!-- MySQL驅(qū)動 -->  
    <dependency>  
        <groupId>com.mysql</groupId>  
        <artifactId>mysql-connector-j</artifactId>  
        <scope>runtime</scope>  
    </dependency>  
    <!-- JWT支持 -->  
    <dependency>  
        <groupId>io.jsonwebtoken</groupId>  
        <artifactId>jjwt-api</artifactId>  
        <version>0.11.5</version>  
    </dependency>  
    <dependency>  
        <groupId>io.jsonwebtoken</groupId>  
        <artifactId>jjwt-impl</artifactId>  
        <version>0.11.5</version>  
        <scope>runtime</scope>  
    </dependency>  
    <dependency>  
        <groupId>io.jsonwebtoken</groupId>  
        <artifactId>jjwt-jackson</artifactId>  
        <version>0.11.5</version>  
        <scope>runtime</scope>  
    </dependency>  
    <!-- Lombok -->  
    <dependency>  
        <groupId>org.projectlombok</groupId>  
        <artifactId>lombok</artifactId>  
        <optional>true</optional>  
    </dependency>  
</dependencies>  

** 第 二 步 : 數(shù) 據(jù) 庫 設(shè) 計 與 實 體 類 **

** 目 的 **

設(shè) 計 用 戶 、 角 色 表 , 并 讓 用 戶 PO 類 實 現(xiàn) Spring Security 的 UserDetails 接 口 。

** 操 作 **

  1. ** 數(shù) 據(jù) 庫 表 設(shè) 計 **
CREATE TABLE sys_user (  
    id BIGINT AUTO_INCREMENT PRIMARY KEY,  
    username VARCHAR(50) NOT NULL UNIQUE COMMENT '用戶名',  
    password VARCHAR(100) NOT NULL COMMENT 'BCrypt加密密碼',  
    email VARCHAR(100) COMMENT '郵箱',  
    enabled BOOLEAN DEFAULT TRUE COMMENT '賬戶是否啟用'  
);  
CREATE TABLE sys_role (  
    id BIGINT AUTO_INCREMENT PRIMARY KEY,  
    role_name VARCHAR(50) NOT NULL UNIQUE COMMENT '角色名稱(無ROLE_前綴)'  
);  
CREATE TABLE sys_user_role (  
    user_id BIGINT,  
    role_id BIGINT,  
    PRIMARY KEY (user_id, role_id),  
    FOREIGN KEY (user_id) REFERENCES sys_user(id),  
    FOREIGN KEY (role_id) REFERENCES sys_role(id)  
);  
  1. ** 實 體 類 UserPo 實 現(xiàn) UserDetails 接 口 **
import com.baomidou.mybatisplus.annotation.TableName;  
import lombok.Data;  
import org.springframework.security.core.GrantedAuthority;  
import org.springframework.security.core.authority.SimpleGrantedAuthority;  
import org.springframework.security.core.userdetails.UserDetails;  
import java.util.Collection;  
import java.util.Set;  
import java.util.stream.Collectors;  
@Data  
@TableName("sys_user")  
public class UserPo implements UserDetails {  
    private Long id;  
    private String username;  
    private String password;  
    private String email;  
    private Boolean enabled = true;  
    private Set<RolePo> roles;  
    @Override  
    public Collection<? extends GrantedAuthority> getAuthorities() {  
        return roles.stream()  
            .map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRoleName()))  
            .collect(Collectors.toList());  
    }  
    @Override  
    public boolean isAccountNonExpired() { return true; }  
    @Override  
    public boolean isAccountNonLocked() { return true; }  
    @Override  
    public boolean isCredentialsNonExpired() { return true; }  
    @Override  
    public boolean isEnabled() { return enabled; }  
}  
  1. ** 角 色 實 體 類 RolePo **
import com.baomidou.mybatisplus.annotation.TableName;  
import lombok.Data;  
@Data  
@TableName("sys_role")  
public class RolePo {  
    private Long id;  
    private String roleName;  
}  

** 第 三 步 : MyBatisPlus Mapper 層 **

** 目 的 **

使 用 MyBatisPlus Mapper 操 作 數(shù) 據(jù) 庫 。

** 操 作 **

  1. ** UserMapper 接 口 **
import com.baomidou.mybatisplus.core.mapper.BaseMapper;  
import org.apache.ibatis.annotations.Param;  
import java.util.Optional;  
public interface UserMapper extends BaseMapper<UserPo> {  
    Optional<UserPo> findByUsername(@Param("username") String username);  
}  
  1. ** RoleMapper 接 口 **
import com.baomidou.mybatisplus.core.mapper.BaseMapper;  
import org.apache.ibatis.annotations.Param;  
public interface RoleMapper extends BaseMapper<RolePo> {  
    Optional<RolePo> findByRoleName(@Param("roleName") String roleName);  
}  

** 第 四 步 : Service 層 — 實 現(xiàn) UserDetailsService **

** 目 的 **

實 現(xiàn) Spring Security 的 UserDetailsService 接 口 , 配 置 密 碼 編 碼 器 。

** 操 作 **

  1. ** 自 定 義 UserDetailsService 實 現(xiàn) 類 **
import lombok.RequiredArgsConstructor;  
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;  
@Service  
@RequiredArgsConstructor  
public class UserDetailsServiceImpl implements UserDetailsService {  
    private final UserMapper userMapper;  
    @Override  
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {  
        UserPo user = userMapper.findByUsername(username)  
            .orElseThrow(() -> new UsernameNotFoundException("用戶不存在:" + username));  
        return user;  
    }  
}  
  1. ** 配 置 密 碼 編 碼 器 **
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
import org.springframework.security.crypto.password.PasswordEncoder;  
@Configuration  
public class PasswordEncoderConfig {  
    @Bean  
    public PasswordEncoder passwordEncoder() {  
        return new BCryptPasswordEncoder();  
    }  
}  

** 第 五 步 : Spring Security 配 置 類 **

** 目 的 **

配 置 認(rèn) 證 規(guī) 則 、 授 權(quán) 規(guī) 則 、 JWT 過 濾 器 。

** 操 作 **

  1. ** 自 定 義 Security 配 置 類 **
import lombok.RequiredArgsConstructor;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.security.authentication.AuthenticationManager;  
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;  
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;  
import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
import org.springframework.security.config.http.SessionCreationPolicy;  
import org.springframework.security.crypto.password.PasswordEncoder;  
import org.springframework.security.web.SecurityFilterChain;  
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;  
@Configuration  
@EnableWebSecurity  
@EnableGlobalMethodSecurity(prePostEnabled = true)  
@RequiredArgsConstructor  
public class SecurityConfig {  
    private final UserDetailsServiceImpl userDetailsService;  
    private final JwtAuthFilter jwtAuthFilter;  
    private final PasswordEncoder passwordEncoder;  
    @Bean  
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {  
        http.csrf(csrf -> csrf.disable())  
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))  
            .authorizeHttpRequests(auth -> auth  
                .requestMatchers("/api/auth/login", "/api/auth/register").permitAll()  
                .requestMatchers("/api/admin/**").hasRole("ADMIN")  
                .requestMatchers("/api/user/**").hasAnyRole("ADMIN", "USER")  
                .anyRequest().authenticated()  
            )  
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)  
            .userDetailsService(userDetailsService)  
            .passwordEncoder(passwordEncoder);  
        return http.build();  
    }  
    @Bean  
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {  
        return config.getAuthenticationManager();  
    }  
}  

** 第 六 步 : JWT 工 具 類 與 過 濾 器 **

** 目 的 **

實 現(xiàn) JWT 生 成 、 驗 證 、 提 取 用 戶 名 , 并 通 過 過 濾 器 轉(zhuǎn) 換 為 認(rèn) 證 信 息 。

** 操 作 **

  1. ** JWT 工 具 類 JwtUtils **
import io.jsonwebtoken.Claims;  
import io.jsonwebtoken.Jwts;  
import io.jsonwebtoken.SignatureAlgorithm;  
import org.springframework.beans.factory.annotation.Value;  
import org.springframework.security.core.userdetails.UserDetails;  
import org.springframework.stereotype.Component;  
import java.util.Date;  
import java.util.function.Function;  
@Component  
public class JwtUtils {  
    @Value("${app.jwt.secret}")  
    private String secret;  
    @Value("${app.jwt.expiration}")  
    private long expiration;  
    public String generateToken(UserDetails userDetails) {  
        return Jwts.builder()  
            .setSubject(userDetails.getUsername())  
            .setIssuedAt(new Date())  
            .setExpiration(new Date(System.currentTimeMillis() + expiration))  
            .signWith(SignatureAlgorithm.HS256, secret)  
            .compact();  
    }  
    public String extractUsername(String token) {  
        return extractClaim(token, Claims::getSubject);  
    }  
    public boolean validateToken(String token, UserDetails userDetails) {  
        final String username = extractUsername(token);  
        return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);  
    }  
    private <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {  
        final Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();  
        return claimsResolver.apply(claims);  
    }  
    private boolean isTokenExpired(String token) {  
        return extractClaim(token, Claims::getExpiration).before(new Date());  
    }  
}  
  1. ** JWT 認(rèn) 證 過 濾 器 JwtAuthFilter **
import lombok.RequiredArgsConstructor;  
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
import org.springframework.security.core.context.SecurityContextHolder;  
import org.springframework.security.core.userdetails.UserDetails;  
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;  
import org.springframework.stereotype.Component;  
import org.springframework.web.filter.OncePerRequestFilter;  
import javax.servlet.FilterChain;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  
@Component  
@RequiredArgsConstructor  
public class JwtAuthFilter extends OncePerRequestFilter {  
    private final JwtUtils jwtUtils;  
    private final UserDetailsServiceImpl userDetailsService;  
    @Override  
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)  
            throws ServletException, IOException {  
        try {  
            String jwt = parseJwt(request);  
            if (jwt != null && jwtUtils.validateToken(jwt)) {  
                String username = jwtUtils.extractUsername(jwt);  
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);  
                UsernamePasswordAuthenticationToken authentication =  
                    new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());  
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));  
                SecurityContextHolder.getContext().setAuthentication(authentication);  
            }  
        } catch (Exception e) {  
            logger.error("無法設(shè)置用戶認(rèn)證: {}", e);  
        }  
        filterChain.doFilter(request, response);  
    }  
    private String parseJwt(HttpServletRequest request) {  
        String headerAuth = request.getHeader("Authorization");  
        if (headerAuth != null && headerAuth.startsWith("Bearer ")) {  
            return headerAuth.substring(7);  
        }  
        return null;  
    }  
}  

** 第 七 步 : 登 錄 接 口 與 資 源 接 口 **

** 目 的 **

編 寫 登 錄 接 口 認(rèn) 證 并 生 成 Token , 編 寫 受 保 護(hù) 資 源 接 口 。

** 操 作 **

  1. ** 登 錄 控 制 器 AuthController **
import lombok.RequiredArgsConstructor;  
import org.springframework.http.ResponseEntity;  
import org.springframework.security.authentication.AuthenticationManager;  
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
import org.springframework.security.core.Authentication;  
import org.springframework.security.core.userdetails.UserDetails;  
import org.springframework.web.bind.annotation.*;  
@RestController  
@RequestMapping("/api/auth")  
@RequiredArgsConstructor  
public class AuthController {  
    private final AuthenticationManager authenticationManager;  
    private final JwtUtils jwtUtils;  
    @PostMapping("/login")  
    public ResponseEntity<JwtResponse> login(@RequestBody LoginRequest loginRequest) {  
        Authentication authentication = authenticationManager.authenticate(  
            new UsernamePasswordAuthenticationToken(  
                loginRequest.getUsername(),  
                loginRequest.getPassword()  
            )  
        );  
        SecurityContextHolder.getContext().setAuthentication(authentication);  
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();  
        String jwt = jwtUtils.generateToken(userDetails);  
        return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getUsername()));  
    }  
}  

** 第 二 部 分 : 權(quán) 限 表 擴(kuò) 展 指 南 — 基 于 角 色 權(quán) 限 模 型 **

** 一 、 數(shù) 據(jù) 庫 擴(kuò) 展 **

** 目 的 **

新 增 權(quán) 限 表 實 現(xiàn) 細(xì) 粒 度 權(quán) 限 控 制 。

** 操 作 **

  1. ** 新 增 權(quán) 限 表 結(jié) 構(gòu) **
CREATE TABLE sys_permission (  
    id BIGINT AUTO_INCREMENT PRIMARY KEY,  
    permission_symbol VARCHAR(100) NOT NULL UNIQUE COMMENT '權(quán)限符號(如 user:add)',  
    permission_name VARCHAR(100) NOT NULL COMMENT '權(quán)限名稱'  
);  
CREATE TABLE sys_role_permission (  
    role_id BIGINT,  
    permission_id BIGINT,  
    PRIMARY KEY (role_id, permission_id),  
    FOREIGN KEY (role_id) REFERENCES sys_role(id),  
    FOREIGN KEY (permission_id) REFERENCES sys_permission(id)  
);  

** 二 、 實 體 類 擴(kuò) 展 **

** 目 的 **

修 改 角 色 與 用 戶 實 體 類 關(guān) 聯(lián) 權(quán) 限 。

** 操 作 **

  1. ** 新 增 權(quán) 限 實 體 類 PermissionPo **
import com.baomidou.mybatisplus.annotation.TableName;  
import lombok.Data;  
import java.util.Set;  
@Data  
@TableName("sys_permission")  
public class PermissionPo {  
    private Long id;  
    private String permissionSymbol;  
    private String permissionName;  
    private Set<RolePo> roles;  
}  
  1. ** 修 改 角 色 實 體 類 RolePo **
import com.baomidou.mybatisplus.annotation.TableName;  
import lombok.Data;  
import java.util.Set;  
@Data  
@TableName("sys_role")  
public class RolePo {  
    private Long id;  
    private String roleName;  
    private Set<PermissionPo> permissions;  
    private Set<UserPo> users;  
}  
  1. ** 修 改 用 戶 實 體 類 UserPo 權(quán) 限 加 載 **
@Override  
public Collection<? extends GrantedAuthority> getAuthorities() {  
    Set<GrantedAuthority> authorities = new HashSet<>();  
    for (RolePo role : roles) {  
        authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));  
        for (PermissionPo permission : role.getPermissions()) {  
            authorities.add(new SimpleGrantedAuthority(permission.getPermissionSymbol()));  
        }  
    }  
    return authorities;  
}  

** 三 、 MyBatisPlus Mapper 擴(kuò) 展 **

** 目 的 **

添 加 權(quán) 限 相 關(guān) Mapper 接 口 。

** 操 作 **

  1. ** PermissionMapper **
import com.baomidou.mybatisplus.core.mapper.BaseMapper;  
import org.apache.ibatis.annotations.Param;  
import java.util.Optional;  
public interface PermissionMapper extends BaseMapper<PermissionPo> {  
    Optional<PermissionPo> findByPermissionSymbol(@Param("symbol") String symbol);  
}  

** 四 、 Service 層 擴(kuò) 展 **

** 目 的 **

實 現(xiàn) 權(quán) 限 管 理 服 務(wù) 。

** 操 作 **

  1. ** 權(quán) 限 管 理 服 務(wù) PermissionService **
import lombok.RequiredArgsConstructor;  
import org.springframework.stereotype.Service;  
import org.springframework.transaction.annotation.Transactional;  
import java.util.Arrays;  
import java.util.stream.Collectors;  
@Service  
@RequiredArgsConstructor  
public class PermissionService {  
    private final PermissionMapper permissionMapper;  
    private final RoleMapper roleMapper;  
    @Transactional  
    public void assignPermissionToRole(Long roleId, String permissionSymbol) {  
        RolePo role = roleMapper.selectById(roleId);  
        PermissionPo permission = permissionMapper.findByPermissionSymbol(permissionSymbol)  
            .orElseGet(() -> {  
                PermissionPo p = new PermissionPo();  
                p.setPermissionSymbol(permissionSymbol);  
                p.setPermissionName(parsePermissionName(permissionSymbol));  
                permissionMapper.insert(p);  
                return p;  
            });  
        role.getPermissions().add(permission);  
        roleMapper.updateById(role);  
    }  
    private String parsePermissionName(String symbol) {  
        return Arrays.stream(symbol.split(":"))  
            .map(word -> word.substring(0, 1).toUpperCase() + word.substring(1))  
            .collect(Collectors.joining(" "));  
    }  
}  

** 五 、 控 制 器 層 擴(kuò) 展 — 使 用 權(quán) 限 注 解 **

** 目 的 **

通 過 @PreAuthorize 注 解 控 制 方 法 權(quán) 限 。

** 操 作 **

  1. ** 用 戶 控 制 器 使 用 權(quán) 限 注 解 **
import org.springframework.security.access.prepost.PreAuthorize;  
import org.springframework.web.bind.annotation.*;  
@RestController  
@RequestMapping("/api/users")  
public class UserController {  
    @PostMapping  
    @PreAuthorize("hasAuthority('user:add')")  
    public ResponseEntity<?> addUser() {  
        return ResponseEntity.ok("添加用戶");  
    }  
    @DeleteMapping("/{id}")  
    @PreAuthorize("hasAuthority('user:delete')")  
    public ResponseEntity<?> deleteUser(@PathVariable Long id) {  
        return ResponseEntity.ok("刪除用戶");  
    }  
}  

** 第 三 部 分 : 數(shù) 據(jù) 權(quán) 限 控 制 — 訂 單 查 詢 只 查 看 自 己 創(chuàng) 建 的 訂 單 **

** 一 、 數(shù) 據(jù) 庫 擴(kuò) 展 — 訂 單 表 **

** 目 的 **

設(shè) 計 訂 單 表 關(guān) 聯(lián) 創(chuàng) 建 人 。

** 操 作 **

  1. ** 訂 單 表 結(jié) 構(gòu) **
CREATE TABLE sys_order (  
    id BIGINT AUTO_INCREMENT PRIMARY KEY,  
    order_no VARCHAR(50) NOT NULL COMMENT '訂單編號',  
    amount DECIMAL(10,2) NOT NULL COMMENT '訂單金額',  
    creator_id BIGINT NOT NULL COMMENT '創(chuàng)建人ID',  
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  
    FOREIGN KEY (creator_id) REFERENCES sys_user(id)  
);  
  1. ** 訂 單 實 體 類 OrderPo **
import com.baomidou.mybatisplus.annotation.TableName;  
import lombok.Data;  
import java.math.BigDecimal;  
import java.time.LocalDateTime;  
@Data  
@TableName("sys_order")  
public class OrderPo {  
    private Long id;  
    private String orderNo;  
    private BigDecimal amount;  
    private Long creatorId;  
    private LocalDateTime createdAt;  
}  

** 二 、 MyBatisPlus Mapper 與 Service **

** 目 的 **

實 現(xiàn) 訂 單 數(shù) 據(jù) 訪 問 與 權(quán) 限 過 濾 。

** 操 作 **

  1. ** OrderMapper **
import com.baomidou.mybatisplus.core.mapper.BaseMapper;  
import org.apache.ibatis.annotations.Param;  
import java.util.List;  
public interface OrderMapper extends BaseMapper<OrderPo> {  
    List<OrderPo> findByCreatorId(@Param("creatorId") Long creatorId);  
}  
  1. ** 訂 單 服 務(wù) 實 現(xiàn) **
import lombok.RequiredArgsConstructor;  
import org.springframework.security.core.context.SecurityContextHolder;  
import org.springframework.stereotype.Service;  
import java.util.List;  
@Service  
@RequiredArgsConstructor  
public class OrderServiceImpl implements OrderService {  
    private final OrderMapper orderMapper;  
    private final UserMapper userMapper;  
    @Override  
    public List<OrderPo> findMyOrders() {  
        UserPo currentUser = getCurrentUser();  
        return orderMapper.findByCreatorId(currentUser.getId());  
    }  
    @Override  
    public OrderPo findOrderById(Long id) {  
        OrderPo order = orderMapper.selectById(id);  
        UserPo currentUser = getCurrentUser();  
        if (!order.getCreatorId().equals(currentUser.getId())) {  
            throw new AccessDeniedException("無權(quán)訪問此訂單");  
        }  
        return order;  
    }  
    private UserPo getCurrentUser() {  
        String username = SecurityContextHolder.getContext().getAuthentication().getName();  
        return userMapper.findByUsername(username).orElseThrow();  
    }  
}  

** 三 、 控 制 器 層 實 現(xiàn) **

** 目 的 **

編 寫 訂 單 相 關(guān) 接 口 , 集 成 數(shù) 據(jù) 權(quán) 限 控 制 。

** 操 作 **

  1. ** 訂 單 控 制 器 **
import org.springframework.security.access.prepost.PreAuthorize;  
import org.springframework.web.bind.annotation.*;  
@RestController  
@RequestMapping("/api/orders")  
@RequiredArgsConstructor  
public class OrderController {  
    private final OrderService orderService;  
    @GetMapping  
    @PreAuthorize("hasAuthority('order:view')")  
    public ResponseEntity<List<OrderPo>> getMyOrders() {  
        List<OrderPo> orders = orderService.findMyOrders();  
        return ResponseEntity.ok(orders);  
    }  
    @GetMapping("/{id}")  
    @PreAuthorize("hasAuthority('order:view')")  
    public ResponseEntity<OrderPo> getOrderById(@PathVariable Long id) {  
        OrderPo order = orderService.findOrderById(id);  
        return ResponseEntity.ok(order);  
    }  
}  

** 總 結(jié) **

通 過 以 上 三 部 分 整 合 , 我 們 實 現(xiàn) 了 Spring Security 前 后 端 分 離 接 入 、 角 色 權(quán) 限 擴(kuò) 展 、 數(shù) 據(jù) 權(quán) 限 控 制 的 完 整 流 程 。 核 心 要 點 如 下 :

  1. ** 基 礎(chǔ) 接 入 ** : 實 現(xiàn) 用 戶 認(rèn) 證 與 JWT 授 權(quán) 。
  2. ** 權(quán) 限 擴(kuò) 展 ** : 通 過 權(quán) 限 表 與 角 色 關(guān) 聯(lián) , 實 現(xiàn) 細(xì) 粒 度 權(quán) 限 控 制 。
  3. ** 數(shù) 據(jù) 權(quán) 限 ** : 在 Service 層 手 動 過 濾 數(shù) 據(jù) , 確 保 用 戶 只 能 查 看 自 己 創(chuàng) 建 的 訂 單 。

整 個 系 統(tǒng) 兼 顧 了 安 全 性 與 靈 活 性 , 適 用 于 中 小 型 項 目 的 權(quán) 限 管 理 需 求 。

到此這篇關(guān)于Spring Security前后端分離接入流程保姆級教程的文章就介紹到這了,更多相關(guān)Spring Security前后端分離接入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java設(shè)計模式之抽象工廠模式詳解

    Java設(shè)計模式之抽象工廠模式詳解

    這篇文章主要介紹了Java設(shè)計模式之抽象工廠模式詳解,抽象工廠是一種為訪問類提供一個創(chuàng)建一組相關(guān)或相互依賴對象的接口,且訪問類無須指定所要產(chǎn)品的具體類就能得到同族的、不同等級的產(chǎn)品的模式結(jié)構(gòu),需要的朋友可以參考下
    2023-09-09
  • PowerJob的OhMyClassLoader工作流程源碼解讀

    PowerJob的OhMyClassLoader工作流程源碼解讀

    這篇文章主要介紹了PowerJob的OhMyClassLoader工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Java中的JVM內(nèi)存分析與故障排查指南

    Java中的JVM內(nèi)存分析與故障排查指南

    Java虛擬機(JVM)是Java應(yīng)用的運行時環(huán)境,其內(nèi)存管理機制直接影響著應(yīng)用的性能和穩(wěn)定性,本文將介紹JVM內(nèi)存分析的基本方法,重點介紹如何使用jmap、jhat和VisualVM等工具進(jìn)行內(nèi)存分析,并探討常見的內(nèi)存泄漏排查方法,需要的朋友可以參考下
    2025-11-11
  • java后端進(jìn)行跨域的幾種方式小結(jié)

    java后端進(jìn)行跨域的幾種方式小結(jié)

    本文主要介紹了java后端進(jìn)行跨域的幾種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • 解決java.sql.SQLException:The?server?time?zone?value?'?D1ú±ê×?ê±??'?is?unrecognized問題

    解決java.sql.SQLException:The?server?time?zone?value?&apo

    這篇文章主要介紹了解決java.sql.SQLException:The?server?time?zone?value?'?D1ú±ê×?ê±??'?is?unrecognized問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Spring Cloud微服務(wù)之間調(diào)用Dubbo的詳細(xì)過程

    Spring Cloud微服務(wù)之間調(diào)用Dubbo的詳細(xì)過程

    SpringCloudAlibabaDubbo是阿里巴巴開源的Dubbo與SpringCloud的深度集成方案,本文介紹Spring Cloud微服務(wù)之間調(diào)用Dubbo的詳細(xì)過程,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • java基于C/S模式實現(xiàn)聊天程序(服務(wù)器)

    java基于C/S模式實現(xiàn)聊天程序(服務(wù)器)

    這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實現(xiàn)聊天程序的服務(wù)器篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Java中的this和super實例淺析

    Java中的this和super實例淺析

    要說this和super就不得不說Java的封裝和繼承了。這篇文章主要介紹了Java中的this和super實例淺析,需要的朋友可以參考下
    2017-03-03
  • 深入了解Java中的過濾器Filter和監(jiān)聽器Listener

    深入了解Java中的過濾器Filter和監(jiān)聽器Listener

    這篇文章主要為大家詳細(xì)介紹了Java中的過濾器Filter和監(jiān)聽器Listener的使用以及二者的區(qū)別,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2022-06-06
  • Mybatis動態(tài)sql超詳細(xì)講解

    Mybatis動態(tài)sql超詳細(xì)講解

    動態(tài)SQL是MyBatis的強大特性之一,顧名思義就是會動的SQL,即是能夠靈活的根據(jù)某種條件拼接出完整的SQL語句,下面這篇文章主要給大家介紹了關(guān)于Mybatis動態(tài)sql的相關(guān)資料,需要的朋友可以參考下
    2023-04-04

最新評論

清新县| 肇东市| 浮山县| 大城县| 镇安县| 白水县| 定远县| 普安县| 辽阳县| 长泰县| 水城县| 麦盖提县| 湟中县| 嘉祥县| 宣威市| 东港市| 巴彦县| 龙泉市| 浦北县| 衡山县| 西昌市| 惠东县| 江油市| 镇安县| 雷州市| 平湖市| 饶阳县| 三都| 绥德县| 鄯善县| 石渠县| 新建县| 运城市| 阳高县| 麻江县| 信丰县| 海门市| 深泽县| 县级市| 新郑市| 秦皇岛市|