• spring boot学习第十三篇:使用spring security控制权限


    该文章同时也讲到了如何使用swagger。

    1、pom.xml文件内容如下:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <parent>
    6. <groupId>org.springframework.boot</groupId>
    7. <artifactId>spring-boot-starter-parent</artifactId>
    8. <version>2.3.5.RELEASE</version>
    9. <relativePath/> <!-- lookup parent from repository -->
    10. </parent>
    11. <groupId>com.hmblogs</groupId>
    12. <artifactId>springboot-security-demo</artifactId>
    13. <version>0.0.1-SNAPSHOT</version>
    14. <name>springboot-security-demo</name>
    15. <description>Demo project for Spring Boot</description>
    16. <properties>
    17. <java.version>1.8</java.version>
    18. </properties>
    19. <dependencies>
    20. <!--devtools热部署-->
    21. <dependency>
    22. <groupId>org.springframework.boot</groupId>
    23. <artifactId>spring-boot-devtools</artifactId>
    24. <optional>true</optional>
    25. <scope>true</scope>
    26. </dependency>
    27. <!-- springboor-->
    28. <dependency>
    29. <groupId>org.springframework.boot</groupId>
    30. <artifactId>spring-boot-starter-web</artifactId>
    31. </dependency>
    32. <dependency>
    33. <groupId>org.springframework.boot</groupId>
    34. <artifactId>spring-boot-starter</artifactId>
    35. </dependency>
    36. <dependency>
    37. <groupId>org.springframework.boot</groupId>
    38. <artifactId>spring-boot-starter-security</artifactId>
    39. </dependency>
    40. <dependency>
    41. <groupId>org.springframework.boot</groupId>
    42. <artifactId>spring-boot-actuator</artifactId>
    43. </dependency>
    44. <dependency>
    45. <groupId>org.springframework.boot</groupId>
    46. <artifactId>spring-boot-starter-test</artifactId>
    47. <scope>test</scope>
    48. </dependency>
    49. <dependency>
    50. <groupId>io.jsonwebtoken</groupId>
    51. <artifactId>jjwt</artifactId>
    52. <version>0.7.0</version>
    53. </dependency>
    54. <!-- swagger -->
    55. <dependency>
    56. <groupId>io.springfox</groupId>
    57. <artifactId>springfox-swagger2</artifactId>
    58. <version>2.9.2</version>
    59. </dependency>
    60. <dependency>
    61. <groupId>io.springfox</groupId>
    62. <artifactId>springfox-swagger-ui</artifactId>
    63. <version>2.9.2</version>
    64. </dependency>
    65. <dependency>
    66. <groupId>org.projectlombok</groupId>
    67. <artifactId>lombok</artifactId>
    68. </dependency>
    69. </dependencies>
    70. <build>
    71. <plugins>
    72. <plugin>
    73. <groupId>org.springframework.boot</groupId>
    74. <artifactId>spring-boot-maven-plugin</artifactId>
    75. </plugin>
    76. </plugins>
    77. </build>
    78. </project>

    2、application.yml文件内容如下:

    1. server:
    2. port: 8088
    3. servlet:
    4. context-path: /springboot-security-demo
    5. spring:
    6. security:
    7. user:
    8. name: user
    9. password: 123456

    3、SpringbootSecurityDemoApplication文件内容如下:

    1. package com.hmblogs;
    2. import org.springframework.boot.SpringApplication;
    3. import org.springframework.boot.autoconfigure.SpringBootApplication;
    4. @SpringBootApplication
    5. public class SpringbootSecurityDemoApplication {
    6. public static void main(String[] args) {
    7. SpringApplication.run(SpringbootSecurityDemoApplication.class, args);
    8. }
    9. }

    4、UserDetailsServiceImpl代码如下:

    1. package com.hmblogs.service.impl;
    2. import java.util.ArrayList;
    3. import java.util.List;
    4. import com.hmblogs.pojo.Admin;
    5. import org.springframework.security.core.GrantedAuthority;
    6. import org.springframework.security.core.authority.SimpleGrantedAuthority;
    7. import org.springframework.security.core.userdetails.User;
    8. import org.springframework.security.core.userdetails.UserDetails;
    9. import org.springframework.security.core.userdetails.UserDetailsService;
    10. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    11. import org.springframework.stereotype.Service;
    12. @Service
    13. public class UserDetailsServiceImpl implements UserDetailsService {
    14. @Override
    15. public UserDetails loadUserByUsername(String username) {
    16. List grantedAuthorities = new ArrayList();
    17. Admin admin = new Admin();
    18. if (username.equals("employee")) {
    19. admin.setUsername("employee");
    20. admin.setPassword("123456");
    21. GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_EMPLOYEE");
    22. grantedAuthorities.add(grantedAuthority);
    23. // 创建用户,用户判断权限
    24. return new User(
    25. admin.getUsername(),
    26. new BCryptPasswordEncoder().encode(admin.getPassword()),
    27. grantedAuthorities);
    28. }
    29. if (username.equals("admin")) {
    30. admin.setUsername("admin");
    31. admin.setPassword("123456");
    32. GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
    33. grantedAuthorities.add(grantedAuthority);
    34. // 创建用户,用户判断权限
    35. return new User(
    36. admin.getUsername(),
    37. new BCryptPasswordEncoder().encode(admin.getPassword()),
    38. grantedAuthorities);
    39. }
    40. return null;
    41. }
    42. }

    5、Admin这一个对象类代码如下:

    1. package com.hmblogs.pojo;
    2. public class Admin {
    3. private String username;
    4. private String password;
    5. public Admin() {
    6. super();
    7. }
    8. public Admin(String username, String password) {
    9. super();
    10. this.username = username;
    11. this.password = password;
    12. }
    13. public String getUsername() {
    14. return username;
    15. }
    16. public void setUsername(String username) {
    17. this.username = username;
    18. }
    19. public String getPassword() {
    20. return password;
    21. }
    22. public void setPassword(String password) {
    23. this.password = password;
    24. }
    25. @Override
    26. public String toString() {
    27. return "Admin [username=" + username + ", password=" + password + "]";
    28. }
    29. }

    6、TestController测试接口类代码如下所示:

    1. package com.hmblogs.controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RequestMethod;
    4. import org.springframework.web.bind.annotation.RestController;
    5. @RestController
    6. @RequestMapping("/test/")
    7. public class TestController {
    8. @RequestMapping(value = "get", method = RequestMethod.GET)
    9. public String get() {
    10. return "success";
    11. }
    12. }

    7、EmployeeController员工权限的员工接口类代码如下所示:

    1. package com.hmblogs.controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RequestMethod;
    4. import org.springframework.web.bind.annotation.RestController;
    5. @RestController
    6. @RequestMapping("/employee/")
    7. public class EmployeeController {
    8. @RequestMapping(value = "greeting", method = RequestMethod.GET)
    9. public String greeting() {
    10. return "hello world";
    11. }
    12. @RequestMapping(value = "login", method = RequestMethod.GET)
    13. public String login() {
    14. return "login success";
    15. }
    16. }

    8、AdminController管理员接口类的代码如下所示:

    1. package com.hmblogs.controller;
    2. import org.springframework.web.bind.annotation.RequestMapping;
    3. import org.springframework.web.bind.annotation.RequestMethod;
    4. import org.springframework.web.bind.annotation.RestController;
    5. @RestController
    6. @RequestMapping("/admin/")
    7. public class AdminController {
    8. @RequestMapping(value = "greeting", method = RequestMethod.GET)
    9. public String greeting() {
    10. return "hello world";
    11. }
    12. @RequestMapping(value = "login", method = RequestMethod.GET)
    13. public String login() {
    14. return "login success";
    15. }
    16. }

    9、SwaggerConfig代码如下:配置swagger

    1. package com.hmblogs.config;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import springfox.documentation.builders.ApiInfoBuilder;
    5. import springfox.documentation.builders.PathSelectors;
    6. import springfox.documentation.builders.RequestHandlerSelectors;
    7. import springfox.documentation.service.ApiInfo;
    8. import springfox.documentation.spi.DocumentationType;
    9. import springfox.documentation.spring.web.plugins.Docket;
    10. import springfox.documentation.swagger2.annotations.EnableSwagger2;
    11. @Configuration
    12. @EnableSwagger2
    13. public class SwaggerConfig {
    14. @Bean
    15. public Docket createRestApi(){
    16. // 添加请求参数,我们这里把token作为请求头部参数传入后端
    17. return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
    18. .select().apis(RequestHandlerSelectors.any())
    19. .paths(PathSelectors.any()).build();
    20. }
    21. private ApiInfo apiInfo(){
    22. return new ApiInfoBuilder()
    23. .title("SpringBoot API Doc")
    24. .description("This is a restful api document of Spring Boot.")
    25. .version("1.0")
    26. .build();
    27. }
    28. }

    10、SecurityConfig代码如下:

    1. package com.hmblogs.config;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.context.annotation.Bean;
    4. import org.springframework.context.annotation.Configuration;
    5. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    6. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    7. import org.springframework.security.config.annotation.web.builders.WebSecurity;
    8. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    9. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    10. import org.springframework.security.core.userdetails.UserDetailsService;
    11. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    12. import org.springframework.security.crypto.password.PasswordEncoder;
    13. @Configuration
    14. @EnableWebSecurity
    15. public class SecurityConfig extends WebSecurityConfigurerAdapter {
    16. @Autowired
    17. private UserDetailsService userDetailsService;
    18. @Bean
    19. public PasswordEncoder passwordEncoder() {
    20. return new BCryptPasswordEncoder();
    21. }
    22. @Override
    23. public void configure(WebSecurity web) throws Exception {
    24. super.configure(web);
    25. }
    26. @Override
    27. public void configure(AuthenticationManagerBuilder auth) throws Exception {
    28. auth.userDetailsService(userDetailsService)
    29. .passwordEncoder(passwordEncoder());//passwoldEncoder是对密码的加密处理,如果user中密码没有加密,则可以不加此方法。注意加密请使用security自带的加密方式。
    30. }
    31. @Override
    32. protected void configure(HttpSecurity http) throws Exception {
    33. http.csrf().disable()//禁用了 csrf 功能
    34. .authorizeRequests()//限定签名成功的请求
    35. .antMatchers("/decision/**","/govern/**","/employee/*").hasAnyRole("EMPLOYEE","ADMIN")//对decision和govern 下的接口 需要 EMPLOYEE 或者 ADMIN 权限
    36. .antMatchers("/employee/login").permitAll()///employee/login 不限定
    37. .antMatchers("/admin/**").hasRole("ADMIN")//对admin下的接口 需要ADMIN权限
    38. .antMatchers("/oauth/**").permitAll()//不拦截 oauth 开放的资源
    39. .anyRequest().permitAll()//其他没有限定的请求,允许访问
    40. .and().anonymous()//对于没有配置权限的其他请求允许匿名访问
    41. .and().formLogin()//使用 spring security 默认登录页面
    42. .and().httpBasic();//启用http 基础验证
    43. }
    44. }

    11.CorsConfig文件代码如下:

    1. package com.hmblogs.config;
    2. import org.springframework.context.annotation.Configuration;
    3. import org.springframework.web.servlet.config.annotation.CorsRegistry;
    4. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    5. @Configuration
    6. public class CorsConfig implements WebMvcConfigurer{
    7. @Override
    8. public void addCorsMappings(CorsRegistry registry) {
    9. registry.addMapping("/**") // 允许跨域访问的路径
    10. .allowedOrigins("*") // 允许跨域访问的源
    11. .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
    12. .maxAge(168000) // 预检间隔时间
    13. .allowedHeaders("*") // 允许头部设置
    14. .allowCredentials(true); // 是否发送cookie
    15. }
    16. }

    12、启动该微服务,验证。

    12.1访问http://localhost:8088/springboot-security-demo/swagger-ui.html

    这里我如果用户名输入admin,密码输入123456,点击登录

    清除浏览器缓存后,再使用employee和123456登录,则会报401

    admin账号能使用admin接口,但是employee账号不能使用admin接口。

     12.2使用admin账号密码和empoyee账号密码尝试employee接口,

    先试用admin账号密码登录

    清除浏览器缓存,再使用employee账号密码登录

    点击登录后,查看响应,如下:

    admin和employee账号都能正常访问employee接口

    达到了预期目的。 

    代码参考:https://github.com/veminhe/spring-security-demo

  • 相关阅读:
    计算机视觉基础【OpenCV轻松入门】:获取图像的ROI
    渗透测试概念详解
    疫情下更合适的开发模式
    React源码分析1-jsx转换及React.createElement
    如何做好银行统一报送系统UI设计
    AIGC启示录:深度解析AIGC技术的现代性与系统性的奇幻旅程
    mysql进程信息出现大量Waiting for table level lock信息的原因,怎么处理?
    MIMO-OFDM无线通信技术-IEEE802.16d模型(Matlab代码)
    拿到第一个用户并提权
    Java easy_trans字典绑定,Java字典注解绑定
  • 原文地址:https://blog.csdn.net/heming20122012/article/details/136344803