#基于session实现认证授权

基于session实现认证授权

1.基本概念

1.2 什么是认证

​ 简而言之,系统中的登录即为认证,认证用户的身份是否合法。进行系统认证可以有效的实现保护用户的隐私数据以及资源,用户的身份合法即可访问该资源。

​ 用户认证就是判断一个用户的身份是否合法的过程,系统去访问资源时,系统要求验证用户的身份信息,身份合法即可继续访问,不合法拒绝访问。常见的用户登录方式有:账号密码登录,二维码登录,手机短信登录,指纹认证,刷脸认证等等。

1.3 什么是会话

​ 用户进行认证之后,为了避免用户每次的操作都需要进行认证,会话就是系统为了保持当前用户的登录状态所提供的机制,常见的方式有session,token等。

1.4 什么是授权

​ 授权是通过用户权限来控制用户访问数据的过程,拥有资源的访问权限即可正常访问,没有则拒绝。(先认证后授权)

1.5 授权的数据模型

	进行用户对访问资源的控制首先需要了解授权的数据模型

​ 授权可以简单的理解为who对what(which)进行how操作

WHO: 即主体(subject),主体一般指的是用户,也可以是程序访问系统中的资源

WHAT:即资源(resource),如系统菜单,页面,按钮,代码方法,系统商品信息,系统订单信息等。系统菜单,页面,按钮,代码方法都属于系统功能资源, 对于web系统每个功能资源通常用一个url,系统商品信息,系统订单信息都属于实体资源(数据资源)。实体资源由资源类型以及资源实例组成,比如商品信息为资源类型,商品编号为001的为资源实例。

HOW:权限/许可(Permission),规定了用户对资源的操作许可,权限离开资源没有意义,如用户查询权限,用户添加权限等等,通过权限可知用户对哪些资源拥有操作的许可。

用户 角色 权限 以及关联表(共5张表)

1.6 RBAC

​ 基于角色的访问(role --),需要改代码,显得冗余。

​ 基于权限的访问控制(resource Based Access Controller),只要给角色分配权限,判断用户是否有该权限即可实现该权限。

2.基于session实现认证

更深刻的认识认证会话授权 (基于springBoot 以及 mybaitsPlus实现)

2.1用户登录认证

//controller	
	@GetMapping("/toLogin")
    @ResponseBody
    public ReturnT<String> login(@RequestParam("username")String username, @RequestParam("pwd")String pwd, HttpSession session){
        AuthenticationRequest authenticationRequest = new AuthenticationRequest(username,pwd);
        UserEntity userInfo = authenticationService.getUserInfo(authenticationRequest);
        session.setAttribute(Constant.USER_SESSION_ID, userInfo.getUsername());
        return ReturnT.success(userInfo.getUsername()+"登录成功");
    }

//Service
	@Autowired
    private UserMapper userMapper;
    @Override
    public UserEntity getUserInfo(AuthenticationRequest authenticationRequest) {
        //先判断认证参数是否为空
        if(authenticationRequest == null
            || StringUtils.isEmpty(authenticationRequest.getUsername())
            || StringUtils.isEmpty(authenticationRequest.getPwd())){
            throw new RuntimeException("用户的账号密码信息为空");
        }
        //查询用户相关的信息
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("username",authenticationRequest.getUsername());
        UserEntity userEntity = userMapper.selectOne(queryWrapper);
        //判断是否存在该用户
        if(userEntity == null){
            throw new RuntimeException("查询不到该用户");
        }
        //判断密码是否正确
        if(!authenticationRequest.getPwd().equals(userEntity.getPwd())){
            throw new RuntimeException("用户名或者密码不正确");
        }
        //认证通过,返回用户信息
        return userEntity;
    }

2.2 实现用户会话功能

用户登录成功之后将用户信息添加到session中,当用户访问页面的时候携带session才能实现对资源的访问,退出登录访问资源失败。

后台相关实现代码如下所示

/**
 * @author daiguojun
 * @date 2021-07-13 22:29
 * 登录控制层
 */
@Controller
@RequestMapping("system")
@Slf4j
public class LoginController {

    @Autowired
    private AuthenticationService authenticationService;

    @GetMapping("/toLogin")
    @ResponseBody
    public ReturnT<String> login(@RequestParam("username")String username, @RequestParam("pwd")String pwd, HttpSession session){
        AuthenticationRequest authenticationRequest = new AuthenticationRequest(username,pwd);
        UserEntity userInfo = authenticationService.getUserInfo(authenticationRequest);
        session.setAttribute(Constant.USER_SESSION_ID, userInfo.getUsername());
        return ReturnT.success(userInfo.getUsername()+"登录成功");
    }

    @GetMapping("login")
    public String toLogin(){
        return "login";
    }

    @GetMapping("/loginOut")
    @ResponseBody
    public ReturnT<String> loginOut(HttpSession session){
        session.removeAttribute(Constant.USER_SESSION_ID);
        return ReturnT.success("退出登录成功");
    }

    @GetMapping("/testSession")
    @ResponseBody
    public ReturnT<String> testSession(HttpSession session){
        String fullName = null;
        Object attribute = session.getAttribute(Constant.USER_SESSION_ID);
        if(attribute == null){
            fullName = "匿名";
            return ReturnT.failed(fullName);
        }else{
            return ReturnT.success("可以访问资源"+attribute);
        }
    }
}

2.3 用户对资源的访问实现

  1. 创建角色表,资源表,以及中间关联表,根据用户登录信息获取到用户的相对应权限
List<ResourceEntity> resourceEntityList = userMapper.getResourceList(userEntity.getId());
UserForm userForm = new UserForm();
BeanUtils.copyProperties(userEntity,userForm);
userForm.setResourceEntityList(resourceEntityList);
  1. 添加拦截器
/**
 * @author daiguojun
 * @date 2021-07-13 22:29
 * 登录拦截器
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    /**
     * 调用方法前执行,根据用户身份对访问资源进行校验
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //从session中取出用户的信息

        Object attribute = request.getSession().getAttribute(Constant.USER_SESSION_ID);
        if(attribute == null){
            //相应未登陆信息给前端
            getResponseMsg(response,"请登陆");
        }
        //session中有信息说明用户以登陆,获取用户相对应的资源
        UserForm userForm = (UserForm)attribute;
        // 将用户访问的url 与 用户权限比较,如果url中包含用户权限,则可以访问
        String url = request.getRequestURI();
        List<ResourceEntity> resourceList = userForm.getResourceEntityList();
        for (ResourceEntity resourceEntity:resourceList){
            if(url.contains(resourceEntity.getResource())){
                return true;
            }
        }
        getResponseMsg(response,"没有权限,拒绝访问");
        return false;
    }

    private void getResponseMsg(HttpServletResponse response, String message) throws IOException {
        PrintWriter writer = response.getWriter();
        writer.print(message);
        writer.close();
        response.resetBuffer();
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

/**
 * @author daiguojun
 * @date 2021-07-13 22:29
 * 配置文件使得拦截器生效
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //配置只拦截某一个controller
        registry.addInterceptor(loginInterceptor).addPathPatterns("/user/**");
    }
}

以上就实现了一个简单的基于session的登录认证授权功能。不同的用户登录之后只能访问到自己相对应权限的接口

文中只有部分关键代码,完整代码以提交到gitee:https://gitee.com/dai_guojun/springboot-security.git

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对你偏爱u

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值