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

SpringBoot3安全管理操作方法

 更新時間:2023年08月14日 09:32:33   作者:知了一笑  
這篇文章主要介紹了SpringBoot3安全管理,在實(shí)際開發(fā)中,最常用的是登錄驗(yàn)證和權(quán)限體系兩大功能,在登錄時完成身份的驗(yàn)證,加載相關(guān)信息和角色權(quán)限,在訪問其他系統(tǒng)資源時,進(jìn)行權(quán)限的驗(yàn)證,保護(hù)系統(tǒng)的安全,文中有詳細(xì)的操作步驟,需要的朋友可以參考下

一、簡介

SpringSecurity組件可以為服務(wù)提供安全管理的能力,比如身份驗(yàn)證、授權(quán)和針對常見攻擊的保護(hù),是保護(hù)基于spring應(yīng)用程序的事實(shí)上的標(biāo)準(zhǔn);

在實(shí)際開發(fā)中,最常用的是登錄驗(yàn)證和權(quán)限體系兩大功能,在登錄時完成身份的驗(yàn)證,加載相關(guān)信息和角色權(quán)限,在訪問其他系統(tǒng)資源時,進(jìn)行權(quán)限的驗(yàn)證,保護(hù)系統(tǒng)的安全;

二、工程搭建

1、工程結(jié)構(gòu)

2、依賴管理

starter-security 依賴中,實(shí)際上是依賴 spring-security 組件的 6.1.1 版本,對于該框架的使用,主要是通過自定義配置類進(jìn)行控制;

<!-- 安全組件 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>${spring-boot.version}</version>
</dependency>

三、配置管理

1、核心配置類

在該類中涉及到的配置非常多,主要是服務(wù)的攔截控制,身份認(rèn)證的處理流程以及過濾器等,很多自定義的處理類通過該配置進(jìn)行加載;

@EnableWebSecurity
@EnableMethodSecurity
@Configuration
public class SecurityConfig {
    /**
     * 基礎(chǔ)配置
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
        // 配置攔截規(guī)則
        httpSecurity.authorizeHttpRequests(authorizeHttpRequests->{
            authorizeHttpRequests
                    .requestMatchers(WhiteConfig.whiteList()).permitAll()
                    .anyRequest().authenticated();
        });
        // 禁用默認(rèn)的登錄和退出
        httpSecurity.formLogin(AbstractHttpConfigurer::disable);
        httpSecurity.logout(AbstractHttpConfigurer::disable);
        httpSecurity.csrf(AbstractHttpConfigurer::disable);
        // 異常時認(rèn)證處理流程
        httpSecurity.exceptionHandling(exeConfig -> {
            exeConfig.authenticationEntryPoint(authenticationEntryPoint());
        });
        // 添加過濾器
        httpSecurity.addFilterAt(authTokenFilter(),CsrfFilter.class);
        return httpSecurity.build() ;
    }
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new AuthExeHandler();
    }
    @Bean
    public OncePerRequestFilter authTokenFilter () {
        return new AuthTokenFilter();
    }
    /**
     * 認(rèn)證管理
     */
    @Bean
    public AuthenticationManager authenticationManager() {
        return new ProviderManager(authenticationProvider()) ;
    }
    /**
     * 自定義用戶認(rèn)證流
     */
    @Bean
    public AbstractUserDetailsAuthenticationProvider authenticationProvider() {
        return new AuthProvider() ;
    }
}

2、認(rèn)證數(shù)據(jù)源

UserDetailsService 是加載用戶特定數(shù)據(jù)的核心接口,編寫用戶服務(wù)類并實(shí)現(xiàn)該接口,提供用戶信息和權(quán)限體系的數(shù)據(jù)查詢和加載,作為用戶身份識別的關(guān)鍵憑據(jù);

@Service
public class UserService implements UserDetailsService {
    @Resource
    private UserBaseMapper userBaseMapper;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;
    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        UserBase queryUser = geyByUserName(userName);
        if (Objects.isNull(queryUser)){
            throw new AuthException("該用戶不存在");
        }
        List<GrantedAuthority> grantedAuthorityList = new ArrayList<>() ;
        grantedAuthorityList.add(new SimpleGrantedAuthority(queryUser.getUserRole())) ;
        return new User(queryUser.getUserName(),queryUser.getPassWord(),grantedAuthorityList);
    }
    public int register (UserBase userBase){
        if (!Objects.isNull(userBase)){
            userBase.setPassWord(passwordEncoder.encode(userBase.getPassWord()));
            userBase.setCreateTime(new Date()) ;
            return userBaseMapper.insert(userBase) ;
        }
        return 0 ;
    }
    public UserBase getById (Integer id){
        return userBaseMapper.selectById(id) ;
    }
    public UserBase geyByUserName (String userName){
        List<UserBase> userBaseList = new LambdaQueryChainWrapper<>(userBaseMapper)
                .eq(UserBase::getUserName,userName).last("limit 1").list();
        if (userBaseList.size() > 0){
            return userBaseList.get(0) ;
        }
        return null ;
    }
}

3、認(rèn)證流程

自定義用戶名和密碼的身份令牌認(rèn)證邏輯,基于用戶名 Username 從上面的用戶服務(wù)類中加載數(shù)據(jù)并校驗(yàn),在驗(yàn)證成功后將用戶的身份令牌返回給調(diào)用者;

@Component
public class AuthProvider extends AbstractUserDetailsAuthenticationProvider {
    private static final Logger log = LoggerFactory.getLogger(AuthProvider.class);
    @Resource
    private UserService userService;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;
    @Override
    protected void additionalAuthenticationChecks(
            UserDetails userDetails, UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        User user = (User) userDetails;
        String loginPassword = authentication.getCredentials().toString();
        log.info("user:{},loginPassword:{}",user.getPassword(),loginPassword);
        if (!passwordEncoder.matches(loginPassword, user.getPassword())) {
            throw new AuthException("賬號或密碼錯誤");
        }
        authentication.setDetails(user);
    }
    @Override
    protected UserDetails retrieveUser(
            String username, UsernamePasswordAuthenticationToken authentication)
            throws AuthenticationException {
        log.info("username:{}",username);
        return userService.loadUserByUsername(username);
    }
}

4、身份過濾器

通過繼承 OncePerRequestFilter 抽象類,實(shí)現(xiàn)用戶身份的過濾器,如果不是白名單請求,需要驗(yàn)證令牌是否正確有效, SecurityContextHolder 默認(rèn)狀態(tài)下使用 ThreadLocal 存儲信息;

@Component
public class AuthTokenFilter extends OncePerRequestFilter {
    @Resource
    private AuthTokenService authTokenService ;
    @Resource
    private AuthExeHandler authExeHandler ;
    @Override
    protected void doFilterInternal(@Nonnull HttpServletRequest request,
                                    @Nonnull HttpServletResponse response,
                                    @Nonnull FilterChain filterChain) throws ServletException, IOException {
        String uri = request.getRequestURI();
        if (Arrays.asList(WhiteConfig.whiteList()).contains(uri)){
            // 如果是白名單直接放行
            filterChain.doFilter(request,response);
        } else {
            String token = request.getHeader("Auth-Token");
            if (Objects.isNull(token) || token.isEmpty()){
                // Token不存在,攔截返回
                authExeHandler.commence(request,response,null);
            } else {
                Object object = authTokenService.getToken(token);
                if (!Objects.isNull(object) && object instanceof User user){
                    UsernamePasswordAuthenticationToken authentication =
                            new UsernamePasswordAuthenticationToken(user, null,user.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    filterChain.doFilter(request,response);
                } else {
                    // Token驗(yàn)證失敗,攔截返回
                    authExeHandler.commence(request,response,null);
                }
            }
        }
    }
}

四、核心功能

1、登錄退出

自定義登錄退出兩個接口,基于用戶名和密碼執(zhí)行上述的身份認(rèn)證流程,如果認(rèn)證成功則返回用戶的身份令牌,在請求「非」白名單接口時需要在請求頭中 Auth-Token:token 攜帶該令牌,在退出時會清除身份信息;

@Service
public class LoginService {
    private static final Logger log = LoggerFactory.getLogger(LoginService.class);
    @Resource
    private AuthTokenService authTokenService ;
    @Resource
    private AuthenticationManager authenticationManager;
    public String doLogin (UserBase userBase){
        AbstractAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                userBase.getUserName().trim(), userBase.getPassWord().trim());
        Authentication authentication = authenticationManager.authenticate(authToken) ;
        User user = (User) authentication.getDetails();
        return authTokenService.createToken(user) ;
    }
    public Boolean doLogout (String authToken){
        SecurityContextHolder.clearContext();
        return authTokenService.deleteToken(authToken) ;
    }
}
@Service
public class AuthTokenService {
    private static final Logger log = LoggerFactory.getLogger(AuthTokenService.class);
    @Resource
    private RedisTemplate<String,Object> redisTemplate ;
    public String createToken (User user){
        String userName = user.getUsername();
        String token = DigestUtils.md5DigestAsHex(userName.getBytes());
        log.info("user-name:{},create-token:{}",userName,token);
        redisTemplate.opsForValue().set(token,user,10, TimeUnit.MINUTES);
        return token ;
    }
    public Object getToken (String token){
        return redisTemplate.opsForValue().get(token);
    }
    public Boolean deleteToken (String token){
        return redisTemplate.delete(token);
    }
}

2、權(quán)限校驗(yàn)

UserWeb 類中提供用戶的注冊接口,在用戶表中創(chuàng)建兩個測試用戶: admin 對應(yīng) ROLE_Admin 角色, user 對應(yīng) ROLE_User 角色,驗(yàn)證如下幾個接口的權(quán)限控制;

select 接口不需要鑒權(quán),攔截器放行即可訪問; getUser 接口校驗(yàn) ROLE_User 角色; getAdmin 接口校驗(yàn) ROLE_Admin 角色; query 接口校驗(yàn)兩個角色中的任意一個即可;

兩個不同用戶登錄獲取到各自的身份令牌,使用不同的令牌請求接口,在 PreAuthorize 驗(yàn)證通過后才可以正常訪問;

@RestController
public class UserWeb {
    @Resource
    private UserService userService ;
    @PostMapping("/register")
    public String register (@RequestBody UserBase userBase){
        return "register-"+userService.register(userBase) ;
    }
    @GetMapping("/select/{id}")
    public UserBase select (@PathVariable Integer id){
        return userService.getById(id) ;
    }
    @PreAuthorize("hasRole('User')")
    @GetMapping("/user/{id}")
    public UserBase getUser (@PathVariable Integer id){
        return userService.getById(id) ;
    }
    @PreAuthorize("hasRole('Admin')")
    @GetMapping("/admin/{id}")
    public UserBase getAdmin (@PathVariable Integer id){
        return userService.getById(id) ;
    }
    @PreAuthorize("hasAnyRole('User','Admin')")
    @GetMapping("/query/{id}")
    public UserBase query (@PathVariable Integer id){
        return userService.getById(id) ;
    }
}

五、參考源碼

文檔倉庫:
https://gitee.com/cicadasmile/butte-java-note
源碼倉庫:
https://gitee.com/cicadasmile/butte-spring-parent

Gitee主頁:https://gitee.com/cicadasmile/butte-java-note

到此這篇關(guān)于SpringBoot3安全管理操作方法的文章就介紹到這了,更多相關(guān)SpringBoot3安全管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java框架Quartz中的Trigger簡析

    Java框架Quartz中的Trigger簡析

    這篇文章主要介紹了Java框架Quartz中的Trigger簡析,所有類型的trigger都有TriggerKey這個屬性,表示trigger的身份;除此之外,trigger還有很多其它的公共屬性,這些屬性,在構(gòu)建trigger的時候可以通過TriggerBuilder設(shè)置,需要的朋友可以參考下
    2023-11-11
  • SpringBoot公共字段自動填充實(shí)現(xiàn)與避坑指南

    SpringBoot公共字段自動填充實(shí)現(xiàn)與避坑指南

    在開發(fā)外賣系統(tǒng)訂單模塊時,我發(fā)現(xiàn)每個實(shí)體類都包含create_time、update_by等重復(fù)字段,手動維護(hù)這些字段不僅效率低下,還容易出錯,本文將分享一套經(jīng)過生產(chǎn)驗(yàn)證的自動化方案,助你徹底擺脫公共字段維護(hù)的煩惱,需要的朋友可以參考下
    2025-05-05
  • redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException異常解決

    redis.clients.jedis.exceptions.JedisMovedDataException?異常是在使用?Jedis?客戶端與?Redis?集群進(jìn)行交互時發(fā)生的,下面就來介紹一下解決方法,感興趣的可以了解一下
    2024-05-05
  • Gradle jvm插件系列教程之Java?Library插件權(quán)威詳解

    Gradle jvm插件系列教程之Java?Library插件權(quán)威詳解

    這篇文章主要介紹了Java?Library插件權(quán)威詳解,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-01-01
  • SpringBoot整合RocketMq實(shí)現(xiàn)分布式事務(wù)

    SpringBoot整合RocketMq實(shí)現(xiàn)分布式事務(wù)

    這篇文章主要為大家詳細(xì)介紹了SpringBoot整合RocketMq實(shí)現(xiàn)分布式事務(wù)的相關(guān)知識,文中的示例代碼講解詳細(xì),有需要的小伙伴可以參考一下
    2024-11-11
  • 詳解Java的繼承

    詳解Java的繼承

    大家好,本篇文章主要講的是詳解Java的繼承,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Spring?Boot?中?@Value注解的使用示例詳解

    Spring?Boot?中?@Value注解的使用示例詳解

    @Value是Spring提供的一個注解,用于從配置文件或其他來源(如系統(tǒng)環(huán)境變量、SpEL表達(dá)式)中讀取值并注入到Bean的字段或方法參數(shù)中,這篇文章主要介紹了SpringBoot中@Value注解的使用,需要的朋友可以參考下
    2025-05-05
  • Spring Boot 使用 logback、logstash、ELK 記錄日志文件的方法

    Spring Boot 使用 logback、logstash、ELK 記錄日志文件的方法

    這篇文章主要介紹了Spring Boot 使用 logback、logstash、ELK 記錄日志文件的思路詳解,文中給大家提到了logback 取代 log4j的理由,需要的朋友可以參考下
    2017-12-12
  • springboot調(diào)用C#封裝的DLL文件中函數(shù)的實(shí)現(xiàn)那

    springboot調(diào)用C#封裝的DLL文件中函數(shù)的實(shí)現(xiàn)那

    本文主要介紹了在Spring Boot中集成C# DLL,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • java使用smslib連接短信貓發(fā)送短信代碼分享

    java使用smslib連接短信貓發(fā)送短信代碼分享

    這篇文章主要介紹了java使用smslib連接短信貓發(fā)關(guān)短信代碼,需要的朋友可以參考下
    2014-02-02

最新評論

屏山县| 仁怀市| 石台县| 边坝县| 襄汾县| 富川| 香格里拉县| 泰顺县| 安义县| 乐都县| 宣汉县| 丰原市| 澎湖县| 平邑县| 邯郸市| 扶沟县| 乌拉特后旗| 金寨县| 丰县| 罗平县| 漳州市| 丹棱县| 桃园市| 卫辉市| 乐陵市| 湟中县| 合山市| 普格县| 仁寿县| 合肥市| 仁怀市| 宣恩县| 南昌县| 库伦旗| 迁安市| 祁连县| 河津市| 宜城市| 郯城县| 尼玛县| 北宁市|