SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权

  新项目引入安全控制

  项目中新近添加了Spring Security安全组件,前期没怎么用过,加之新版本少有参考,踩坑四天,终完成初步解决方案.其实很简单,Spring Security5相比之前版本少了许多配置,操作起来更轻量

  MariaDb登录配置加密策略

  SpringSecurity5在执行登录认证时,需预设加密策略.

  坑一:加密策略配置,验密始终不通过,报错401

  坑二:本地重写的UserDetailsService实现类在注入的时候找不到,目前图省事直接用了 @Qualifier制定

  其它,实体类user实现UserDetails,role实现GrantedAuthority与之前版本并有太大变动,可参考很多,不做赘述

  代码如下:  

  /**
     * 项目中重写的 UserDetailsService接口的实现类,需指定
     */
    @Qualifier("userService")
    @Autowired
    private UserDetailsService userDetailsService;
    /**
     * 初始验证登录  从内存中取密码
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());

    }

  跨域的问题

  Springboot2.0.3处理跨域的时候特别简单,只需要在

  @EnableWebSecurity  @Configuration  @EnableGlobalMethodSecurity(prePostEnabled = true)  @Order(-1)    等修饰下的配置类中的HttpSecurity中,加上 cors()即可,完全不需要写过滤器包装HttpServletResponse的操作  

  登录报错403,权限不足  这里的解决方案很多,因为本文项目不大,直接关闭 csrf (跨站请求伪造)即可  同上,csrf().disable()即可.     最大坑--跨域打开,每次登录返回为匿名用户anonymousUser  问题描述:    跨域已打开,使用Swagger访问都没有问题,前后端分离时,SpringSecurity也正常工作,最终还是登录不成功,返回匿名用户    关闭匿名用户即 anonymous().disable(),直接报错401,用户名或密码错误  遇到这个问题,一直纠结在跨域上,却没有深入去查看前端http请求上给出的信息,原因很简单,登录时重定向的问题  在HttpSecurity中,在选择 formLogin()时,其后会选择各种成功失败的url,然后代码上去实现相关的接口,其实就入坑了.  注意:在前端使用ajax登录时,SpringSecurity只能通过重写相关成功/失败/退出等的处理器handler来完成相关处理逻辑  完整配置类代码:
@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(-1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    CustomizeAuthenticationSuccessHandler customizeAuthenticationSuccessHandler;
    @Autowired
    CustomizeAuthenticationFailHandler customizeAuthenticationFailHandler;
    @Autowired
    CustomizeAuthenticationAccessDenied customizeAuthenticationAccessDenied;
    @Autowired
    CustomizeAuthenticationLogout customizeAuthenticationLogout;

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .csrf().disable()
                .anonymous().disable()
                .cors().and().httpBasic()
                .and()
                // 登录成功页面与登录失败页面
                .formLogin()
                .successHandler(customizeAuthenticationSuccessHandler).failureHandler(customizeAuthenticationFailHandler).permitAll().and()
                // 权限不足,即403时跳转页面
                .exceptionHandling().accessDeniedHandler(customizeAuthenticationAccessDenied).authenticationEntryPoint(new UnauthorizedEntryPoint())
                .and().logout().logoutSuccessHandler(customizeAuthenticationLogout).permitAll().and()
                .authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
                // 无需权限 即可访问
                .antMatchers("/logout").permitAll()
                // 需要USER角色才可访问
                .antMatchers("/person/**").hasRole("PERSON")
                // 需要ADMIN角色才可访问
                .antMatchers("/user/**").hasRole("ADMIN");
    }

    /**
     * 项目中重写的 UserDetailsService接口的实现类,需指定
     */
    @Qualifier("userService")
    @Autowired
    private UserDetailsService userDetailsService;
    /**
     * 初始验证登录  从内存中取密码
     * @param auth
     * @throws Exception
     */
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());

    }

}

  重写的登录成功处理器代码如下:

@Component
public class CustomizeAuthenticationSuccessHandler implements AuthenticationSuccessHandler {

    private static final Logger logger = LoggerFactory.getLogger(CustomizeAuthenticationSuccessHandler.class);

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response, Authentication authentication)
            throws IOException, ServletException {

        logger.info("AT onAuthenticationSuccess(...) function!");

        WebAuthenticationDetails details = (WebAuthenticationDetails) SecurityContextHolder.getContext().getAuthentication().getDetails();
        logger.info("login--IP:"+details.getRemoteAddress());

        SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication1 = context.getAuthentication();
        Object principal = authentication1.getPrincipal();
        Object principal1 = authentication.getPrincipal();

        String name = authentication.getName();
        logger.info("login--name:"+name+" principal:"+principal+" principal1:"+principal1);

        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(JSONObject.toJSONString(ResponseData.ok().putDataValue("user",principal)
                    .putDataValue("name",name)));
        } catch (IOException e){
            e.printStackTrace();
        }finally {
            if (out != null) {
                out.close();
            }
        }
    }
}

原文地址:https://www.cnblogs.com/nyatom/p/9239651.html

时间: 2024-11-05 14:56:56

SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权的相关文章

Springboot2 Vue 前后端分离 整合打包 docker镜像

项目使用springboot2和Vue前后端分离开发模式,再整合,容器化部署. 主要说明下大体的流程,扫除心里障碍,期间遇到的问题请自行解决. 首先说下Vue打包: 1.在Vue项目目录下运行命令打包:npm run build:prod --report 生成需要使用的dist文件,打包后会出现在项目目录下.(目录结构可能会不同) 按照如下方式整合到springboot项目中,resources在main目录下. (结构不同的话)一样拆到static目录下,static下面直接跟img.css

SpringBoot 和Vue前后端分离入门教程(附源码)

作者:梁小生0101 juejin.im/post/5c622fb5e51d457f9f2c2381 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模式内容聚合 4. 排序算法内容聚合 5. 多线程内容聚合 前端工具和环境: Node.js V10.15.0 Vue.js V2.5.21 yarn: V1.13.0 IDE:VScode 后端工具和环境: Maven: 3.52 jdk: 1.8 MySql: 14.14 IDE: IDEA S

python 记录Django与Vue前后端分离项目搭建

python 记录Django与Vue前后端分离项目搭建 参考链接: https://blog.csdn.net/liuyukuan/article/details/70477095 1. 安装python与vue 2. 创建Django项目 django-admin startproject ulb_manager 3. 进入项目并创建名为backeng的app cd ulb_manager   python manage.py startapp backend 4. 使用vue-cli创建v

Spring Boot + Vue 前后端分离开发,权限管理的一点思路

在传统的前后端不分的开发中,权限管理主要通过过滤器或者拦截器来进行(权限管理框架本身也是通过过滤器来实现功能),如果用户不具备某一个角色或者某一个权限,则无法访问某一个页面. 但是在前后端分离中,页面的跳转统统交给前端去做,后端只提供数据,这种时候,权限管理不能再按照之前的思路来. 首先要明确一点,前端是展示给用户看的,所有的菜单显示或者隐藏目的不是为了实现权限管理,而是为了给用户一个良好的体验,不能依靠前端隐藏控件来实现权限管理,即数据安全不能依靠前端. 这点就像普通的表单提交一样,前端做数据

ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分离普遍存在的问题跨域(CORS)请求问题.因此就有了这篇文章如何启用ASP.NET WebApi 中的 CORS 支持. 一.解决Vue报错:OPTIONS 405 Method Not Allowed问题: 错误重现: index.umd.min.js:1 OPTIONS http://local

vue前后端分离

axios前后端交互 安装 一定要安装到`项目目录下 cnpm install axios 配置 在main.js中配置 //配置axios import axios from 'axios' Vue.prototype.$axios = axios; 在组件中发送ajax请求 created(){ //发送axios请求 this.$axios({ url:this.$settings.base_url+'/cars/', method:'get', params:{ } }).then(re

SSM+Vue前后端分离Demo

网上找了一份实习,需要做这几道题,所以用了两天时间,顺便整理一下SSM+Vue的前后端的搭建, 项目地址:https://github.com/LIRUILONGS/SSM-Vue-.git 题目是这样的: 题一:1.数据单表增删改查,分页查询.数据字段不少于3个.2.项目框架使用SSM架构,不允许使用逆向工程生成项目.3.数据库使用MYSQL(版本号5.6或5.7)使用maven管理jar包. 题二:1.数据两张表增删改查,两张表带有逻辑关系,分页查询.数据字段不少于3个.2.项目框架使用SS

Spring Boot + Vue 前后端分离,两种文件上传方式总结

在Vue.js 中,如果网络请求使用 axios ,并且使用了 ElementUI 库,那么一般来说,文件上传有两种不同的实现方案: 通过 Ajax 实现文件上传 通过 ElementUI 里边的 Upload 组件实现文件上传 两种方案,各有优缺点,我们分别来看. 准备工作 首先我们需要一点点准备工作,就是在后端提供一个文件上传接口,这是一个普通的 Spring Boot 项目,如下: SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/

vue前后端分离端口号代理配置

vue cli3.x 使用方式: 在vue.config.js加入 devServer: { proxy: 'http://localhost:8080' } 前端直接axios 调用方式: 官网:https://cli.vuejs.org/zh/config/#devserver 原文地址:https://www.cnblogs.com/weibanggang/p/12539144.html