欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot+SpringSecurity實現(xiàn)認證的流程詳解

 更新時間:2024年05月19日 08:27:28   作者:小薛cOde  
這篇文章主要介紹了SpringBoot+SpringSecurity實現(xiàn)認證的流程,文中通過代碼示例和圖文結合的方式講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下

整合springSecurity

對應springboot版本,直接加依賴,這樣版本不會錯

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

比如我這里是2.6.4的版本。對應的springSecurity版本是5.6.x

沒找到springSecurity對應springboot依賴對應表

但springboot2.x基本對應security的5.x版本

3.x對應6.x版本

最基本的概念:

  • 認證和授權

    • 認證(Authentication):用戶輸入賬戶密碼,系統(tǒng)讓其登錄到系統(tǒng)里
    • 授權(authorities):用戶的權限不同,他們能在系統(tǒng)做的事情都不同

springSecurity如何實現(xiàn)認證

UsernamePasswordAuthenticationToken可以允許你傳入username和password參數(shù)

關鍵代碼

UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());

然后調(diào)用UserDetailsService的loadUserByUsername方法根據(jù)username查出數(shù)據(jù)庫中的這個用戶

 @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //查詢用戶信息
        User user = userMapper.findByColumnAndValue("user_name", username);
        if(user==null){
            throw new UsernameNotFoundException("用戶名或密碼錯誤");
        }
        //查詢用戶權限
        List<String> perms = menuMapper.selectPermsByUserId(user.getId());
        return new LoginUser(user,perms);
    }

然后可以調(diào)用authenticationManager.authenticate方法對用戶輸入的賬號密碼進行驗證,密碼會經(jīng)過passwordEncoder去加密,然后和數(shù)據(jù)庫中該用戶的賬號密碼比對。

//加密器 bean
@Bean
    public PasswordEncoder PasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
//驗證邏輯
Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);

如果通過,返回一個Authentication對象,封裝了該用戶的信息。像這樣:

這時需要將信息保存到Security上下文。

像這樣:

SecurityContextHolder.getContext().setAuthentication(authenticate);

這樣,后面的代碼就可以通過SecurityContextHolder.getContext()來獲取當前用戶了。

如果失敗,springSecurity會拋出一個異常:AuthenticationException。

框架有默認異常處理器,但一般你可以自定義異常處理器,并把錯誤信息和業(yè)務整合。像這樣:

@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        ResponseResult<Object> noAuthentication = ResponseResult.noAuthentication("認證失敗");
        String json = JSON.toJSONString(noAuthentication);
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control","no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().println(json);
        response.getWriter().flush();
    }
}

其他接口如何校驗用戶是否登錄

需要一個檢查登錄過濾器,這個過濾器要通過檢查token,并解析出用戶信息,保存到Security上下文

@Component
public class CheckLoginFilter extends OncePerRequestFilter {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisCache redisCache;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 如果請求路徑是登錄接口,直接放行
        String requestURI = request.getRequestURI();
        if ("/user/login".equals(requestURI)) {
            filterChain.doFilter(request, response);
            return;
        }
?
        //獲取token
        String token = request.getHeader("token");
        if(token==null){
            //springSecurity有一個過濾器會自動檢查Context有沒有認證
            throw new RuntimeException("token為空");
        }
        //解析token,獲取userId
        Claims claims = JwtUtils.parserClaimsFromToken(token);
        if(claims==null){
            throw new RuntimeException("token非法");
        }
        //從redis數(shù)據(jù)庫里取
        Long userId = claims.get("userId", Long.class);
        String redisKey="login:"+userId;
        LoginUser loginUser = (LoginUser) redisCache.getCacheObject(redisKey);
        if(loginUser==null){
            throw new RuntimeException("沒有登錄:redis沒有登錄key");
        }
        //todo 從數(shù)據(jù)庫查該用戶的權限,先寫死
        //將用戶信息存入Authentication
        //權限存入,全局設置為該請求已經(jīng)認證過
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginUser,null,loginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        //checkLogin完成,放行
        filterChain.doFilter(request,response);
?
    }
}

基本流程圖

以上就是SpringBoot+SpringSecurity實現(xiàn)認證的流程詳解的詳細內(nèi)容,更多關于SpringBoot SpringSecurity認證流程的資料請關注腳本之家其它相關文章!

相關文章

最新評論