0
点赞
收藏
分享

微信扫一扫

云E办后端项目总结


 

项目实现的功能:

.登录的验证码功能

.操作员的认证和授权功能

.操作员的对应角色的更新

.部门管理

.员工管理

.菜单管理

.职称管理

登录和授权过程:

先将登录接口进行放行,请求会先通过jwt tokenfilter,如果前端请求没有携带jwttoken,那么就是未认证的状态,jwttokenfilter将会直接放行,在login接口中会首先比对验证码是否正确,如果正确的话,在usernamepasswordauthenticationfilter中调用重写过的loadUserByUsername方法,先将传入的用户名信息去数据库中查询,将查询得到的用户信息封装成UserDetails对象返回,然后进行密码的校验,如果也通过的话就将用户信息和权限信息封装成Authentication对象存入redis中,并通过用户名生成一个jwt令牌返回给前端。

用户登录之后访问其他接口时,首先会通过jwt tokenfilter进行判断,如果此时携带有jwt令牌,在jwt tokenfilter中对前端携带的jwt进行解析得到对应用户的用户名,根据此用户名去redis中查询对应的用户信息和权限信息,如果redis中存在用户信息,就将用户信息封装成Authentication对象,并存在SecurityContextHolder中。

在CustomFilter中,会获取请求的url,将可以访问该url的角色保存成一个String[],如果没有匹配的url默认为登录即可访问,将需要的角色名设置为"ROLE_LOGIN",之后请求会经过FilterSecurityIntecopter,如果所需要的角色是"ROLE_LOGIN",则直接放行,否则的话判断当前登录用户的角色和SpringSecurity所需要的角色是否匹配,如果匹配则允许访问,不匹配则报异常。

package com.xxxx.server.config.filter;

import com.xxxx.server.Utils.RedisCache;
import com.xxxx.server.config.security.JwtTokenUtil;
import com.xxxx.server.pojo.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
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;

/**
 * @program: yeb
 * @description: Jwt的过滤器
 * @author: 周文杰
 * @create: 2022-04-14 21:11
 **/
@Component
public class jwtAuthenticationTokenFilter  extends OncePerRequestFilter {

    @Value("${jwt.tokenHeader}")

    private String tokenHeader;

    @Value("${jwt.tokenHead}")

    private String tokenHead;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private RedisCache redisCache;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                    FilterChain filterChain) throws ServletException, IOException {
        //前端携带token的格式应该为:tokenHeader:tokenHead jwt令牌
        String header = httpServletRequest.getHeader(tokenHeader);
        if (!StringUtils.hasText(header)){
            filterChain.doFilter(httpServletRequest,httpServletResponse);
            return;
        }
        //存在token
        String username = null;
        if (header != null && header.startsWith(tokenHead)){
            String authToken = header.substring(tokenHead.length());
            username = jwtTokenUtil.getUserNameFromToken(authToken);


//            //token存在,但是未登录
//            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null){
//                //登录
//                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
//                //验证token是否有效,重新设置用户对象
//                if (jwtTokenUtil.validateToken(authToken,userDetails)){
//                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
//                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
//                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//                }
//            }
        }

        //从redis中获取用户信息
        String redisKey="user_name"+username;
        Admin user = redisCache.getCacheObject(redisKey);
        if (ObjectUtils.isEmpty(user)){
            throw  new RuntimeException("用户信息不存在");
        }
        //验证通过后将用户信息存入SecurityContextHolder中
        UsernamePasswordAuthenticationToken authenticationToken=new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
}

云E办后端项目总结_redis

问题:使用自己创建的用户时,无法从redis中获取用户信息?


举报

相关推荐

0 条评论