博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot2.0.3 + SpringSecurity5.0.6 + vue 前后端分离认证授权
阅读量:5872 次
发布时间:2019-06-19

本文共 5004 字,大约阅读时间需要 16 分钟。

  新项目引入安全控制

  项目中新近添加了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());    }}

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

@Componentpublic 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

你可能感兴趣的文章
关于Tomcat下项目中文名在Windows和Linux下编码混乱问题解决
查看>>
struts中的xwork源码下载地址
查看>>
Android硬件抽象层(HAL)深入剖析(二)
查看>>
CDays–4 习题一至四及相关内容解析。
查看>>
L3.十一.匿名函数和map方法
查看>>
前端自动化构建工具webpack (一)之webpack安装 和 设置webpack.confi.js
查看>>
java面向对象高级分层实例_实体类
查看>>
Guice 练习 constructorbindings demo
查看>>
android aapt 用法 -- ApkReader
查看>>
[翻译]用 Puppet 搭建易管理的服务器基础架构(3)
查看>>
Android -- AudioPlayer
查看>>
Python大数据依赖包安装
查看>>
Android View.onMeasure方法的理解
查看>>
Node.js 爬虫初探
查看>>
ABP理论学习之仓储
查看>>
centos7下使用yum安装mysql
查看>>
How can I set ccshared=-fPIC while executing ./configure?
查看>>
2.移植uboot-添加2440单板,并实现NOR、NAND启动
查看>>
hadoop-2.6.5安装
查看>>
vmware虚拟机里的LINUX不能上网的原因一:虚拟网卡设置
查看>>