Spring Boot对Spring Security提供了自动化配置方案,同时这也是在Spring Boot项目中使用Spring Security的优势,因此Spring Security整合进Spring Boot项目中是非常容易的。

一.Spring Security 的基本用法

1.1 创建项目,添加依赖


对应依赖如下:

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

1.2 添加一个controller接口

@GetMapping("/hello")public String hello(){return "hello everyone!";}

1.3 启动项目进行测试


  启动后,Spring Security 默认的用户名为user,密码是每次启动项目启动的时候随机生成,如图:

  项目启动日志中可以看到生成的默认密码,登录成功之后,就可以访问之前的接口了。

1.4 配置用户名和密码

  当用户需要自己的账号和密码时,可以在application.properties配置文件中配置默认的用户名,密码以及用户角色等,相关配置如下:

spring.security.user.name=jiangbin
spring.security.user.password=123456
spring.security.user.roles=admin

1.5 基于内存的认证

  开发者可以继承WebSecurityConfigureAdapter实现Spring Security更多的自定义配置,例如基于内存的配置,配置如下:

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {/*** spring security 5.x 引入了多种密码加密,开发者必须引入一种* 这里使用NoOpPasswordEncoder,即不对密码进行加密* @return*/@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 基于内存的认证* @param auth* @throws Exception*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("root").password("123456").roles("ADMIN", "DBA").and().withUser("admin").password("123456").roles("ADMIN", "USER").and().withUser("jiangbin").password("123456").roles("USER");}

  继承WebSecurityConfigurerAdapter,并重写configure(AuthenticationManagerBuilder auth)方法,在这个方法中配置三个用户以及他们的密码和角色。

  注:基于内存的认证在配置角色的时候不需要添加前缀"ROLE_",然而在基于数据库的认证中配置角色时需要添加前缀"ROLE_"。

1.5 HttpSecurity

  如上已经实现了认证功能,但是受保护的资源都是默认的,而且不能更具实际情况进行角色管理,如果要实现这些功能,就可以实现WebSecurityConfigurerAdapter中另外一个方法,代码如下:

 /*** 指定受保护的资源 和 根据实际情况进行角色管理* @param http* @throws Exception*/@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("ADMIN", "USER").antMatchers("/dba/**").access("hasRole('ADMIN') and hasRole('DBA')").anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll()  //表示和登录相关的接口都不要认证即可访问.and().csrf().disable();}

  authorizeRequests()方法开启HttpSecurity配置。9-14行表示用户访问某种模式的Url必须具备什么样的角色,如访问"/admin/**“模式的Url必须具备ADMIN的角色。15-16行表示除了前面定义的URl模式之外,用户访问其他的模式Url必须登录才能访问。18行开启表单登录,19行表示登录接口为”/login",主要方便移动端和Ajax调用登录接口,登录参数中用户命名必须为username,密码必须命名为password。permitAll()方法表示所有与登录有关的接口都不需要认证即可访问。22-23行表示关闭csrf。

1.6表单登录详细配置

  登录表单一直使用Spring Security提供的页面,登录成功后也是默认的页面跳转,如今前后端分离开始成为主流,在前后端的开发中,数据是通过Json进行的,此时登录成功将不在进行页面跳转,而实通过一段JSON提示。

                .and().formLogin().loginProcessingUrl("/login").usernameParameter("name").passwordParameter("passwd").successHandler(new AuthenticationSuccessHandler() {@Overridepublic void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException {Object principal = auth.getPrincipal(); //获取登录用户的信息resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();resp.setStatus(200);Map<String, Object> map = new HashMap<>();map.put("status", 200);map.put("msg", principal);ObjectMapper om = new ObjectMapper();String s = om.writeValueAsString(map);out.write(s);out.flush();out.close();}}).failureHandler(new AuthenticationFailureHandler() {@Overridepublic void onAuthenticationFailure(HttpServletRequest req, HttpServletResponse resp, AuthenticationException e) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();resp.setStatus(401);Map<String, Object> map = new HashMap<>();map.put("status", 401);if (e instanceof LockedException) {map.put("msg", "账户被锁定,登录失败");} else if (e instanceof BadCredentialsException) {map.put("msg", "账户或密码输入错误,登陆失败");} else if (e instanceof CredentialsExpiredException) {map.put("msg", "密码已过期,登陆失败");} else if (e instanceof AccountExpiredException) {map.put("msg", "账户已过期,登录失败");} else if (e instanceof DisabledException) {map.put("msg", "账户被禁用");}ObjectMapper om = new ObjectMapper();String s = om.writeValueAsString(map);out.write(s);out.flush();out.close();}}).permitAll()  //表示和登录相关的接口都不要认证即可访问.and()

  successHandler()方法表示登录成功的处理逻辑,用户登录成功可以返回一个页面,也可以返回一段JSON数据,这里我们返回的是一段JSON数据,在onAuthenticationSuccess()方法中参数Authentication表示获取当前登录用户的信息。
  failureHandler()方法表示登录失败的处理逻辑,登录失败可以通过参数AuthenticationException获取登录失败的原因。

1.7注销登录配置

                .and().logout()  //开启注销配置.logoutUrl("/logout")  //注销登录请求Url.clearAuthentication(true)  //是否清除身份认证.invalidateHttpSession(true)  //是否使Session失效.addLogoutHandler(new LogoutHandler() {   //可以完成一些数据清除工作@Overridepublic void logout(HttpServletRequest req, HttpServletResponse resp, Authentication auth) {}}).logoutSuccessHandler(new LogoutSuccessHandler() {  //处理注销成功后的业务逻辑。如返回一段json或跳转到登录页面@Overridepublic void onLogoutSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth) throws IOException, ServletException {resp.setContentType("application/json;charset=utf-8");PrintWriter out = resp.getWriter();out.write("注销登录成功!");out.flush();out.close();}}).and()

1.8 多个HttpSecurity

  业务比较复杂时,开发者可以配置多个HttpSecurity,实现对WebSecurityConfigurerAdapter的多次拓展,代码如下:

@Configuration
public class MultiHttpSecurityConfig {@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Autowiredpublic void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password("$2a$10$qLDuJyeHKPjrcrmdeALpsODPyY694c3Pv7tRCMTjftOuShH2s1arC").roles("ADMIN", "USER").and().withUser("jiangbin").password("$2a$10$iKqkzWsAkos1xXIWmtvZb.zZTQ6qKHxnKsuPr2IIolX4Jv.Dfn/xW").roles("USER");}@Configuration@Order(1)public static class AdminHttpSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasRole("ADMIN");}}@Configurationpublic static class OtherHttpSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginProcessingUrl("/login").permitAll().and().csrf().disable();}}
}

  实现多个HttpSecurity时,主类不要继承WebSecurityConfigurerAdapter,在主类中创建静态内部类继承WebSecurityConfigurerAdapter即可,同时在类上加上@Configration和@Order注解,@Order表示优先级,数字越小优先级越大,未加@Order注解的优先级最小。

1.9 密码加密

@BeanPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(10);}

  Spring Security提供了多种密码的加密方式,官方推荐使用 BCryptPasswordEncoder,它使用BCrypt强哈希函数,开发者在使用时可以提供strength和SecureRandom实例。strenth越大,密钥迭代的次数越多,密钥迭代次数为2^strength。Strength取值在4-31之间,默认为10。

1.10 方法安全

  开发者可以通过注解来灵活的配置方法安全,如果要使用相关注解,首先需要@EnableGlobalMethodSecurity注解开启基于注解的安全配置。

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true , securedEnabled = true)  //开启方法安全配置
public class WebSecurityConfigWithGlobal {}

  prePostEnabled = true会开启 @PreAuthorize和@PostAuthorize两个注解,@PreAuthorize注解会在方法执行之前进行验证,@PostAuthorize注解在方法执行之后进行验证。而securedEnabled = true会开启@Secured注解。
  开启注解后,写一个Service进行测试。代码如下:

@Service
public class HelloService {@Secured("ROLE_ADMIN")public String admin(){return "hello admim";}@PreAuthorize("hasRole('Admin') and hasRole('DBA')")public String dba(){return "hello dba";}@PreAuthorize("hasAnyRole('ADMIN','USER','DBA')")public String user(){return "hello user";}
}

   @Secured(“ROLE_ADMIN”)注解表示访问该方法需要ADMIN角色,这里需要在角色前加上前缀"ROLE_"。下面两个注解表示的意思也是如此。

Spring Boot2 总结(二) Spring Security的基本配置相关推荐

  1. Spring Boot2.x-10 基于Spring Boot 2.1.2 + Mybatis 2.0.0实现多数据源,支持事务

    文章目录 概述 思路 步骤 Step1 多数据源配置文件applicaiton.yml Step2 初始化多个数据源 Step3 配置多个数据源 验证测试 支持事务 Step1 配置类中通过@Bean ...

  2. Spring Boot2.x-09 基于Spring Boot 2.1.2 + Mybatis使用自定义注解实现数据库切换

    文章目录 概述 场景说明:读写分离 操作步骤 工程结构 Step1 自定义注解 Step2 数据源定义 Step3 配置文件配置数据源 Step4 数据源实例化DatasourceConfig Ste ...

  3. Spring 学习之 二----Spring创建对象的三种方式

    最近在系统的学习Spring,现在就Spring的一些知识进行总结. 我们知道Spring是一个开放源代码的设计层面的框架,他主要解决的是业务逻辑层与其他各层之间松耦合的问题. Spring 有三个核 ...

  4. spring boot 学习(二)spring boot 框架整合 thymeleaf

    spring boot 框架整合 thymeleaf spring boot 的官方文档中建议开发者使用模板引擎,避免使用 JSP.因为若一定要使用 JSP 将无法使用. 注意:本文主要参考学习了大神 ...

  5. Spring Boot系列二 Spring @Async异步线程池用法总结

    转载 自 https://blog.csdn.net/hry2015/article/details/67640534 1. TaskExecutor Spring异步线程池的接口类,其实质是java ...

  6. Spring Data 系列(二) Spring+JPA入门(集成Hibernate)

    通过[Spring Data 系列(一) 入门]的介绍,通过对比的方式认识到Spring提供的JdbcTemplate的强大功能.通过使用JdbcTemplate,操作数据库,不需要手动处理Conne ...

  7. SpringSecurity权限管理框架系列(六)-Spring Security框架自定义配置类详解(二)之authorizeRequests配置详解

    1.预置演示环境 这个演示环境继续沿用 SpringSecurit权限管理框架系列(五)-Spring Security框架自定义配置类详解(一)之formLogin配置详解的环境. 2.自定义配置类 ...

  8. 7. Spring Boot2.5 安全机制与 REST API 身份验证实战

    文章目录 Spring Boot2.5 安全机制与 RESTAPI 身份验证实战 一.Java Spring Boot 2.5 安全机制 Java Spring Boot 2.0 安全机制 安全漏洞 ...

  9. Spring Boot2.x-12 Spring Boot2.1.2中Filter和Interceptor 的使用

    文章目录 Interceptor 拦截器 拦截器中方法的执行流程 传统项目拦截器的配置 Spring Boot2.1.2整合拦截器Interceptor 示例 Step1 实现HandlerInter ...

最新文章

  1. 怎么切换用户_走进通信:4G手机跟基站是怎么“交流”的
  2. 颠覆农业思维-国际农民丰收节贸易会·万祥军:大粮食概念
  3. oracle查看字典结构体,Oracle-17-数据字典查看约束信息
  4. Node.js~ioredis处理耗时请求时连接数瀑增
  5. 【玩转树莓派】使用 sinopia 搭建私有 npm 服务器
  6. 查询程序崩溃日志_PC 崩溃报告途径 amp; 临时解决方法
  7. P2770 航空路线问题(网络流)
  8. js原型、原型链、作用链、闭包全解
  9. 前端如何快速上手 Web 3D 游戏的开发
  10. 将序列设置为字段的默认值 - oracle
  11. Acwing:最长回文子串
  12. 织梦php 文章采集规则,织梦输入网址采集单个网页功能发布 不需要写采集规则一键采集...
  13. 搜索引擎 —海量数据搜索
  14. 7-4 华氏度转摄氏度 (5分) java
  15. Millet谷仓区块链和电子商务及Token相结合的产物
  16. html5 调用本地街景,H5案例分享:在移动端调用腾讯街景
  17. 草丛效果-shader forge
  18. golang的http
  19. Python开发过哪些知名网站和游戏?
  20. Windows编译libjpeg库

热门文章

  1. echarts修改背景线条及坐标轴颜色样式
  2. 测试工具LoadRunner和OpenSTA比较分析
  3. 串口调试助手版本合集
  4. automake编译工程
  5. 基于SSM的垃圾分类管理系统-含论文【数据库设计、论文、源码、开题报告】
  6. 一整套美团面经(给对象超用心整理的)
  7. 爬虫实战 | 爬取东方财富网股票数据
  8. 咧咧一下“汉语编程”
  9. win7服务器只显示4g内存,安装win7 64位系统后8G内存只显示4G可用解决方法
  10. linux fat16 id,解析FAT16文件系统