Springboot+Vue实现在线聊天室项目-集成springSecurity配置实现登录的权限控制

Springboot+Vue实现在线聊天室项目目录

该聊天室为大二上学期计算机网络大作业,并且是本人第一次使用vue实现前后端分离的项目,前端架构尚未熟悉可能会出现一些不妥之处,还请大佬们指出。(本文章写于项目整体完成上线之后,所以一些细节并未写出)

pom导入springSecurity

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

编写配置文件

在config文件夹中创建注解为

@Configuration
@EnableWebSecurity
并继承WebSecurityConfigurerAdapter的配置类
其中依赖注入UserService用于密码检测,corsFilter用于跨域配置
在这里插入图片描述

配置http的security

在这里插入图片描述
其中,.sessionManagement().invalidSessionUrl("/session/invalid").用于登录权限过期时的跳转,当sesion中的信息过期时,前端再次访问会跳转到session/invalid接口。这里在前端加一个拦截器检测该接口的返回,如果出现则前端跳转到登录页面
在这里插入图片描述
这里配置/register、/invalid两个接口不受权限控制,为permitAll。formLogin也为permitAll,即登录、注册、过期三个接口不受权限限制。

配置http登录成功、失败、注销
.successHandler(new AuthenticationSuccessHandler() {
                    @Override
                    public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        System.out.println("登陆成功");
                        Map<String, Object> map = new HashMap<>();
                        map.put("msg", "登录成功!");
                        map.put("principal", authentication.getPrincipal());
                        resp.setContentType("application/json;charset=utf-8");
                        resp.setHeader("Access-Control-Allow-Origin","http://www.guoruijava.xyz");
                        resp.setHeader("Access-Control-Allow-Credentials", "true");
                        resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
                        resp.setHeader("Access-Control-Max-Age", "3600");
                        resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                        PrintWriter out = resp.getWriter();
                        // 对象转json传输给前端
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .failureHandler(new AuthenticationFailureHandler() {
                    @Override
                    public void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {
                        System.out.println("登录失败");
                        Map<String, Object> map = new HashMap<>();
                        resp.setContentType("application/json;charset=utf-8");
                        resp.setHeader("Access-Control-Allow-Origin", "http://www.guoruijava.xyz");
                        resp.setHeader("Access-Control-Allow-Credentials", "true");
                        resp.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
                        resp.setHeader("Access-Control-Max-Age", "3600");
                        resp.addHeader("Access-Control-Allow-Headers", "token,accesstoken,Content-type");
                        System.out.println("设置resp" + resp.toString());
                        PrintWriter out = resp.getWriter();
                        if (e instanceof BadCredentialsException){
                            map.put("msg","账号或密码输入错误,登录失败!");
                        }else{
                            map.put("msg","出现异常,登录失败!");
                        }
                        // 对象转json传输给前端
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .permitAll()
                .and()
                .logout()
                .logoutUrl("/logout")
                .permitAll()
                .logoutSuccessHandler(new LogoutSuccessHandler() {
                    @Override
                    public void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication authentication) throws IOException, ServletException {
                        Map<String, Object> map = new HashMap<>();
                        map.put("state", 200);
                        map.put("msg", "注销成功!");
                        resp.setContentType("application/json;charset=utf-8");
                        resp.setHeader("Access-Control-Allow-Origin","http://www.guoruijava.xyz");
                        resp.setHeader("Access-Control-Allow-Credentials", "true");
                        resp.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
                        resp.setHeader("Access-Control-Max-Age", "3600");
                        resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                        PrintWriter out = resp.getWriter();
                        // 对象转json传输给前端
                        out.write(new ObjectMapper().writeValueAsString(map));
                        out.flush();
                        out.close();
                    }
                })
                .permitAll();
配置数据库的security权限
@Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            System.out.println("权限管理");
            auth.userDetailsService(userService);
        }

security的拦截器会调用这里userService中的loadUserByUsername方法,这个方法是实现UserDetailsService接口重写的方法

@Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User use = userDao.getUserByAccount(s);
        if (use == null){
            throw new UsernameNotFoundException("用户名不存在");
        }else{
            System.out.println(new User(use.getId(),use.getName(),use.getImg(),use.getAccount(),use.getPassword(),"ROLE_USER",
                    userDao.getMyFriends(use.getFriends().split("\\|")),userDao.getMyRooms(use.getRooms().split("\\|"))).toString());
            return new User(use.getId(),use.getName(),use.getImg(),use.getAccount(),use.getPassword(),"ROLE_USER",
           userDao.getMyFriends(use.getFriends().split("\\|")),userDao.getMyRooms(use.getRooms().split("\\|")));
        }
    }

登录成功后,由security将用户信息principal存入容器中,这个信息可以通过SecurityContextHolder.getContext().getAuthentication().getPrincipal()来获取(用于后续用户操作时获取用户的信息权限)
。这里将获取用户id作为静态方法放在UserService中

public static int getUserIdCurrent(){
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        int id = ((User)principal).getId();
        return id;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值