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

SpringSecurity認(rèn)證授權(quán)全流程解讀

 更新時間:2025年06月19日 09:54:08   作者:Nice-or-77  
這篇文章主要介紹了SpringSecurity認(rèn)證授權(quán)全流程,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

SpringSecurity認(rèn)證流程:loadUserByUsername()方法內(nèi)部實(shí)現(xiàn)。

實(shí)現(xiàn)步驟

構(gòu)建一個自定義的service接口,實(shí)現(xiàn)SpringSecurity的UserDetailService接口。

建一個service實(shí)現(xiàn)類,實(shí)現(xiàn)此loadUserByUsername方法。

調(diào)用登錄的login接口,會經(jīng)過authenticationManager.authenticate(authenticationToken)方法。此方法會調(diào)用loadUserByUsername方法。

方法內(nèi)部做用戶信息的查詢,判斷用戶名和密碼是否正確,這是第一道認(rèn)證。

@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {


    private final SysUserMapper sysUserMapper;
    //用戶登錄請求/login,自動調(diào)用方法
    //根據(jù)用戶名獲取用戶信息
    //UserDetails 存儲用戶信息,包括用戶名,密碼,權(quán)限
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUsername, username);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        if (Objects.isNull(sysUser)){
            throw new UsernameNotFoundException("用戶名不存在");
        }
        //認(rèn)證成功回UserDetails對象

        return new LoginUser(sysUser);
    }


}

@ToString
public class LoginUser implements UserDetails {

    private SysUser sysUser;

    public LoginUser(SysUser sysUser) {
        this.sysUser = sysUser;
    }

    // 權(quán)限
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return List.of();
    }

    @Override
    public String getPassword() {
        return sysUser.getPassword();
    }

    @Override
    public String getUsername() {
        return sysUser.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;
    }
}

如果沒有查到信息就拋出異常。

如果查到信息了再接著查用戶的權(quán)限信息,返回權(quán)限信息到loginUser實(shí)體。

此實(shí)體實(shí)現(xiàn)了SpringSecurity自帶的userDetail接口。實(shí)現(xiàn)了getAuthorities方法。

每次查詢權(quán)限都會調(diào)用此方法。

查詢到的權(quán)限,會被返回到login接口。進(jìn)行后續(xù)操作。

如果認(rèn)證通過,通過身份信息中的userid生產(chǎn)一個jwt。

把完整的用戶信息作為value,token作為key存入redis。

@RestController
@Tag(name = "認(rèn)證模塊", description = "認(rèn)證模塊")
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

    //注入AuthenticationManager(認(rèn)證管理器)
    private final AuthenticationManager authenticationManager;

    private final JwtUtils jwtUtils;

    @PostMapping("/login")
    @Operation(summary = "登錄")
    public Result login(@RequestParam("username") String username, @RequestParam("password") String password) {
        System.out.println(username + password);
        //登錄邏輯
        //調(diào)用UserDetailsService.loadUserByUsername方法獲取
        //不能直接調(diào)用,需要通過AuthenticationManager進(jìn)行認(rèn)證

        Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authenticate = null;
        try {
            authenticate = authenticationManager.authenticate(authentication);
        } catch (BadCredentialsException e) {
            return Result.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR);
        }

        //認(rèn)證成功方法token
        String token=jwtUtils.generateToken(authenticate);
        return Result.success(token);
    }
}

@Configuration
@EnableWebSecurity // 開啟web安全
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final IgnoredUrl ignoredUrl;


    /**
     * 配置認(rèn)證管理器 AuthenticationManager
     * 作用:用于身份認(rèn)證
     * 參數(shù):UserDetailsService, PasswordEncoder
     */
    @Bean
    public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        return new ProviderManager(provider);
    }

    /**
     * 密碼編碼器
     *
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //關(guān)閉csrf防護(hù),否則回導(dǎo)致登錄失敗
        http.csrf(a -> a.disable()); //禁用SCRF
        //配置安全攔截規(guī)則
        http.authorizeHttpRequests(req ->
                                   req.requestMatchers(ignoredUrl.getUrls())
                                   .permitAll()
                                   .anyRequest().authenticated());
        /**
         * 配置登錄頁
         */
        http.formLogin(form -> form
                       .loginPage("/")
                       .successForwardUrl("/index") //登錄成功跳轉(zhuǎn)頁面
                       .loginProcessingUrl("/login")//登錄處理url
                       .failureForwardUrl("/error") //登錄失敗跳轉(zhuǎn)頁面
                       //                .usernameParameter("name")//自定義用戶名參數(shù)
                       //                .passwordParameter("password")//自定義密碼參數(shù)
                      );

        return http.build();
    }
}
@Component
public class JwtUtils {

    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.expiration}")
    private Integer expiration;

    /**
     *
     */

    public String generateToken(Authentication authentication) {
        Date now = new Date();
        Date expirationDate = DateUtil.offsetSecond(now, expiration);
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", authentication.getName());//用戶名
        claims.put("exp", expirationDate);
        //        claims.put();
        return JWTUtil.createToken(claims, secret.getBytes());
    }
}
@Component
@Data
@ConfigurationProperties(prefix = "security.ignored")
@ToString
public class IgnoredUrl {

    private String[] urls;
}

登錄成功

登陸失敗

總結(jié)

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用java生成激活碼和密鑰的方法

    使用java生成激活碼和密鑰的方法

    本文主要介紹了java生成激活碼和密鑰的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 使用SpringBoot配置多數(shù)據(jù)源的經(jīng)驗(yàn)分享

    使用SpringBoot配置多數(shù)據(jù)源的經(jīng)驗(yàn)分享

    這篇文章主要介紹了使用SpringBoot配置多數(shù)據(jù)源的經(jīng)驗(yàn)分享,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Spring Cloud調(diào)用Ribbon的步驟

    Spring Cloud調(diào)用Ribbon的步驟

    Ribbon是Netflix發(fā)布的開源項(xiàng)目,主要功能是提供客戶端的軟件負(fù)載均衡算法和服務(wù)調(diào)用。本文將講述Spring Cloud調(diào)用Ribbon的方法
    2021-05-05
  • Springboot整合SpringSecurity實(shí)現(xiàn)登錄認(rèn)證和鑒權(quán)全過程

    Springboot整合SpringSecurity實(shí)現(xiàn)登錄認(rèn)證和鑒權(quán)全過程

    這篇文章主要介紹了Springboot整合SpringSecurity實(shí)現(xiàn)登錄認(rèn)證和鑒權(quán)全過程,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Mybatis多條數(shù)據(jù)只返回一條的問題及解決

    Mybatis多條數(shù)據(jù)只返回一條的問題及解決

    文章介紹了在MyBatis中進(jìn)行聯(lián)查時,如果只返回主表數(shù)據(jù)而子表數(shù)據(jù)相同,可能會導(dǎo)致重復(fù)數(shù)據(jù)的問題,解決方法是在主表對象中添加一個臨時字段,并將子表的不同數(shù)據(jù)封裝到主表中,從而避免重復(fù)數(shù)據(jù)的返回
    2026-03-03
  • 解決struts2 攔截器修改request的parameters參數(shù)失敗的問題

    解決struts2 攔截器修改request的parameters參數(shù)失敗的問題

    這篇文章主要介紹了解決struts2 攔截器修改request的parameters參數(shù)失敗的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • C語言指針數(shù)組案例詳解

    C語言指針數(shù)組案例詳解

    這篇文章主要介紹了C語言指針數(shù)組案例詳解,本文通過案例詳細(xì)的解釋了指針與數(shù)組的初始化還有關(guān)系與應(yīng)用,需要的朋友可以參考下這篇文章
    2021-07-07
  • Java線程在什么情況下可以終止

    Java線程在什么情況下可以終止

    Thread線程類自帶的stop方法,但是jdk不建議使用,因?yàn)閟top方法終止線程只是強(qiáng)行終止,內(nèi)存中部分值可能已發(fā)生變化,并未保證數(shù)據(jù)的一致性,將會導(dǎo)致線程安全問題,那么在什么情況下可以終止線程呢,本篇帶你探究一下
    2022-04-04
  • Springboot-admin整合Quartz實(shí)現(xiàn)動態(tài)管理定時任務(wù)的過程詳解

    Springboot-admin整合Quartz實(shí)現(xiàn)動態(tài)管理定時任務(wù)的過程詳解

    Quartz是一款Java編寫的開源任務(wù)調(diào)度框架,同時它也是Spring默認(rèn)的任務(wù)調(diào)度框架,它的作用其實(shí)類似于Timer定時器以及ScheduledExecutorService調(diào)度線程池,這篇文章主要介紹了Springboot-admin整合Quartz實(shí)現(xiàn)動態(tài)管理定時任務(wù),需要的朋友可以參考下
    2023-04-04
  • 性能爆棚的實(shí)體轉(zhuǎn)換復(fù)制工具M(jìn)apStruct使用詳解

    性能爆棚的實(shí)體轉(zhuǎn)換復(fù)制工具M(jìn)apStruct使用詳解

    這篇文章主要為大家介紹了性能爆棚的實(shí)體轉(zhuǎn)換復(fù)制工具M(jìn)apStruct使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評論

敦煌市| 屯留县| 谢通门县| 汝阳县| 兴义市| 同江市| 绿春县| 绥滨县| 汶上县| 南漳县| 舒城县| 南乐县| 谢通门县| 常熟市| 修水县| 酒泉市| 乐都县| 禄劝| 甘泉县| 土默特右旗| 佳木斯市| 怀宁县| 防城港市| 奉新县| 辽宁省| 来宾市| 屏边| 方城县| 阳山县| 泽州县| 都安| 平塘县| 蓝山县| 清流县| 陵水| 文昌市| 柯坪县| 孝感市| 东莞市| 随州市| 黄梅县|