SpringSecurity的编写流程

chatgpt/2023/9/24 0:43:33

目录

主要流程: 

具体实现:


主要流程: 

(特殊)1、如果你需要返回json格式字符串,那么你首先需要编写相应的处理器,如果不需要则可直接写配置类

2、编写配置类

3、编写认证授权相关的mapper方法和service方法

4、编写认证和授权逻辑

        4.1、编写认证授权逻辑的类,实现UserDetailsService接口,重现loadUserByUserName方法

        提示:不要忘记将该类放入spring容器中,不然security无法使用该逻辑

        4.2、根据用户名查询用户

        4.3、根据用户名查询相关权限

        4.4、将用户的权限集合转换为security的权限集合

        4.5、构建UserDetails对象,放入用户名、密码、security权限集合

        4.6、返回构建好的UserDetails对象

5、编写鉴权配置

6、使用不同权限的用户登录,查看他们是否能访问这些接口

具体实现:

(特殊)1、如果你需要返回json格式字符串,那么你首先需要编写相应的处理器

提示:BaseResult是一个统一返回结果集,这里返回结果只是一个参考,因为我的业务时需要返回json格式字符串,具体处理器如何操作还是看业务

登录成功处理器

//登录成功处理器
public class MyLoginSuccessHandler implements AuthenticationSuccessHandler {@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("text/json;charset=utf-8");BaseResult baseResult = new BaseResult(200,"登录成功",null);response.getWriter().write(JSON.toJSONString(baseResult));}
}

登录失败处理器

//登录失败处理器
public class MyLoginFailureHandler implements AuthenticationFailureHandler {@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {response.setContentType("text/json;charset=utf-8");BaseResult baseResult = new BaseResult(402,"用户名或密码错误",null);response.getWriter().write(JSON.toJSONString(baseResult));}
}

注销成功处理器

//登出成功处理器
public class MyLogoutSuccessHandler implements LogoutSuccessHandler {@Overridepublic void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setContentType("text/json;charset=utf-8");BaseResult baseResult = new BaseResult(200,"注销成功",null);response.getWriter().write(JSON.toJSONString(baseResult));}
}

未登录处理器

//未登录处理器
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {response.setContentType("text/json;charset=utf-8");BaseResult baseResult = new BaseResult(401,"用户未登录",null);response.getWriter().write(JSON.toJSONString(baseResult));}
}

权限不足处理器

//权限不足处理器
public class MyAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {response.setContentType("text/json;charset=utf-8");BaseResult baseResult = new BaseResult(403,"权限不足",null);response.getWriter().write(JSON.toJSONString(baseResult));}
}

2、编写配置类

提示1:编写配置类的时候不要忘了PasswordEncoder密码解析器

提示2:登录请求一定要是post请求,否则无法请求无法到达

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//登录配置http.formLogin().usernameParameter("username")//登录用户名项.passwordParameter("password")//登录密码项.loginProcessingUrl("/admin/login")//登录提交路径.successHandler(new MyLoginSuccessHandler())//登录成功处理器.failureHandler(new MyLoginFailureHandler());//登录失败处理器//权限拦截器配置http.authorizeRequests().antMatchers("/login").permitAll()//登录页面不用拦截.antMatchers("/admin/login").permitAll()//登录路径不用拦截.anyRequest().authenticated();//其他路径都要拦截//注销配置http.logout().logoutUrl("/admin/logout")//注销提交路径.logoutSuccessHandler(new MyLogoutSuccessHandler())//注销成功处理器.invalidateHttpSession(true)//清除session.clearAuthentication(true);//清除认证状态//异常处理http.exceptionHandling().accessDeniedHandler(new MyAccessDeniedHandler())//权限不足处理器.authenticationEntryPoint(new MyAuthenticationEntryPoint());//未登录处理器//关闭csrf防护http.csrf().disable();//开启跨域访问http.cors();}@Beanpublic PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}
}

3、编写认证授权相关的mapper方法和service方法,具体跟业务相关

4、编写认证和授权逻辑

编写逻辑的时候需要使用到认证和授权相关的mapper和service,所以我们需要引入service,service中使用了相关mapper

具体流程:

1、编写认证授权逻辑的类,实现UserDetailsService接口,重现loadUserByUserName方法

        提示:不要忘记将该类放入spring容器中,不然security无法使用该逻辑

2、根据用户名查询用户

3、根据用户名查询相关权限

4、将用户的权限集合转换为security的权限集合

(这个Permission.getUrl()很重要,它就是用户拥有的权限所对应的url,后期我们编写鉴权配置的时候就是通过这个url去判断该用户是否有对应权限的

5、构建UserDetails对象,放入用户名、密码、security权限集合

6、返回构建好的UserDetails对象

//认证和授权逻辑
@Service
public class MyUserDetailsService implements UserDetailsService {@DubboReference //需要使用到认证授权相关的mapper和serviceprivate AdminService adminService;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//根据用户名查询用户Admin admin = adminService.findByUserName(username);if(admin == null){throw new UsernameNotFoundException("用户未找到");}//根据用户名查询权限List<Permission> permissions = adminService.findAllPermission(username);//将我的权限集合转为security的权限集合List<GrantedAuthority> grantedAuthorities = new ArrayList<>();if(permissions.get(0) != null){ //判断该用户是否有权限,如果没有权限则不需要转换for (Permission permission:permissions) {//拿出权限中的url,方便日后的鉴权grantedAuthorities.add(new SimpleGrantedAuthority(permission.getUrl()));}}UserDetails userDetails = User.withUsername(admin.getUsername()).password(admin.getPassword()).authorities(grantedAuthorities).build();return userDetails;}
}

5、编写鉴权配置

        1、在启动类上方开启注解配置访问权限

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ShoppingManagerApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(ShoppingManagerApiApplication.class, args);
    }

}
 

        2、在相关控制器上方添加注解,配置需要有的权限

/**
     * 分页查询管理员
     * @param page 页数
     * @param size 每页条数
     * @return vo
     */
    @PreAuthorize("hasAnyAuthority('/admin/search')")
    @GetMapping("/search")
    public BaseResult<Page<Admin>> search(int page,int size){
        Page<Admin> adminPage = adminService.search(page, size);
        return BaseResult.ok(adminPage);
    }

通过这个注解就会自动判断,当前登录的用户是否有/admin/search权限,这些权限的url都是我们在认证和授权逻辑的时候放入的

6、使用不同权限的用户登录,查看他们是否能访问这些接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-5314301.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

分布式ID性能评测:CosId VS 美团 Leaf

环境 MacBook Pro (M1)JDK 17JMH 1.36运行在本机 Docker 内的 mariadb:10.6.4 运行 CosId SegmentChainId 模式&#xff0c;基准测试代码&#xff1a; Benchmarkpublic long generate() {return segmentChainId.generate();}Leaf 基准测试代码&#xff1a; Benchmarkpublic l…

ERROR: No matching distribution found for wxpyhton

ERROR: No matching distribution found for wxpyhton pip install 库包名 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.compip install wxpython -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

AngularJS 和 Vue.JS区别

AngularJS 和 Vue.JS 都是流行的 JavaScript 框架&#xff0c;用于构建 Web 应用程序。以下是它们之间的一些主要区别&#xff1a; 1. 背景&#xff1a; AngularJS 由 Google 的前雇员 Misko Hevery 开发&#xff0c;并于 2009 年首次发布。它是一种基于 JavaScript 的前端框…

如何使用Webman框架实现多语言支持和国际化功能?

如何使用Webman框架实现多语言支持和国际化功能&#xff1f; Webman是一款轻量级的PHP框架&#xff0c;提供了丰富的功能和扩展性&#xff0c;使得开发人员能够更加高效地开发Web应用程序。其中&#xff0c;多语言支持和国际化功能是Web应用程序中非常重要的一项功能&#xff…

计算机视觉:卷积层的参数量是多少?

本文重点 卷积核的参数量是卷积神经网络中一个重要的概念,它决定了网络的复杂度和计算量。在深度学习中,卷积操作是一种常用的操作,用于提取图像、语音等数据中的特征。卷积神经网络的优势点在于稀疏连接和权值共享,这使得卷积核的参数相较于传统的神经网络要少很多。 举例…

【技巧】通过 CMD 走代理下载 Vue

通过 CMD 走代理下载 Vue 在学习或者工作中&#xff0c;有时上网走的是代理模式&#xff0c;就是在浏览器里面配置代理服务的那种。后来在下载 Vue 组件的时候显示请求超时。此时才发先&#xff0c;浏览器代理只能在浏览器里生效&#xff0c;cmd 中不生效&#xff0c;那该怎么办…

大厂HR经常会问到的Java线程池面试题

一、什么是线程池 线程池和数据库连接池非常类似&#xff0c;可以统一管理和维护线程&#xff0c;减少没有必要的开销。 二、为什么要使用线程池 因为在项目开发过程中频繁的开启线程或者停止线程&#xff0c;线程需要重新被CPU从就绪状态调度到运行状态&#xff0c;需要发生C…

c++基础知识(inline、auto、nullptr)

⭐️ 内联函数 &#x1f4ac; 为什么会有内联函数&#xff1f;   内联函数其实是为了弥补 c 的缺陷&#xff0c;比如当我们遇到了一些少量逻辑和代码的情况时&#xff0c;而这些少量的代码又需要被重复使用多次&#xff08;swap&#xff09;&#xff0c;我们往往会封装成为一…
推荐文章