security初体验(一)

x33g5p2x  于2022-03-02 转载在 其他  
字(11.6k)|赞(0)|评价(0)|浏览(273)

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.6.4</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.yl</groupId>
  12. <artifactId>security</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>security</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>11</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-security</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-web</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-test</artifactId>
  31. <scope>test</scope>
  32. </dependency>
  33. <dependency>
  34. <groupId>org.springframework.security</groupId>
  35. <artifactId>spring-security-test</artifactId>
  36. <scope>test</scope>
  37. </dependency>
  38. </dependencies>
  39. <build>
  40. <plugins>
  41. <plugin>
  42. <groupId>org.springframework.boot</groupId>
  43. <artifactId>spring-boot-maven-plugin</artifactId>
  44. </plugin>
  45. </plugins>
  46. </build>
  47. </project>

2.security.config

  1. package com.yl.security.config;
  2. import com.yl.security.handler.LogOutSuccessHandler;
  3. import com.yl.security.handler.LoginFailHandler;
  4. import com.yl.security.handler.LoginSuccessHandler;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  9. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
  10. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  11. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  12. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  13. import org.springframework.security.crypto.password.NoOpPasswordEncoder;
  14. import org.springframework.security.crypto.password.PasswordEncoder;
  15. @Configuration
  16. @EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) //开启全局方法安全功能
  17. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  18. @Autowired
  19. LoginSuccessHandler loginSuccessHandler;
  20. @Autowired
  21. LoginFailHandler loginFailHandler;
  22. @Autowired
  23. LogOutSuccessHandler logOutSuccessHandler;
  24. //使用不加密的编码方式
  25. // @Bean
  26. // PasswordEncoder passwordEncoder() {
  27. // return NoOpPasswordEncoder.getInstance();
  28. // }
  29. @Bean
  30. PasswordEncoder passwordEncoder() {
  31. return new BCryptPasswordEncoder();
  32. }
  33. // 基于内存的用户名和密码认证
  34. @Override
  35. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  36. auth.inMemoryAuthentication()
  37. // 密码设置为123
  38. .withUser("root").password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO").roles("user")
  39. .and().withUser("admin").password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO").roles("admin");
  40. }
  41. //匹配拦截路径,处理器等
  42. @Override
  43. protected void configure(HttpSecurity http) throws Exception {
  44. http.authorizeRequests()
  45. .antMatchers("/admin/**").hasRole("admin") //静态配置哪些角色访问才能访问指定路径
  46. // .antMatchers("/user/**").hasAnyRole("admin","user")
  47. .antMatchers("/user/**").access("hasAnyRole('user','admin')")
  48. .anyRequest().authenticated() //其他所有请求登录成功后才能访问
  49. .and()
  50. .formLogin()
  51. .loginProcessingUrl("/doLogin") //登录处理usrl,注意:登录请求为post请求
  52. .loginPage("/login") // 登录的页面
  53. .usernameParameter("username") //登录的用户名参数名
  54. .passwordParameter("password") //登录的密码参数名
  55. .successHandler(loginSuccessHandler) //登录成功后的处理器
  56. .failureHandler(loginFailHandler) //登录失败后的处理器
  57. .permitAll() // 登录接口允许所有人访问
  58. .and()
  59. .logout()
  60. .logoutUrl("/logOut") // 登出接口
  61. .logoutSuccessHandler(logOutSuccessHandler) //登出成功处理器
  62. .and()
  63. .csrf().disable(); //关闭csrf保护
  64. }
  65. }

3.登录成功处理器

  1. package com.yl.security.handler;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import org.springframework.security.core.Authentication;
  4. import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
  5. import org.springframework.stereotype.Component;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11. import java.util.HashMap;
  12. import java.util.Map;
  13. //登录成功处理器
  14. @Component
  15. public class LoginSuccessHandler implements AuthenticationSuccessHandler {
  16. @Override
  17. public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
  18. response.setContentType("application/json;charset=utf-8");
  19. PrintWriter writer = response.getWriter();
  20. Map<String,Object> map = new HashMap<>();
  21. map.put("status",200);
  22. map.put("msg",authentication.getPrincipal());
  23. writer.write(new ObjectMapper().writeValueAsString(map));
  24. writer.flush();
  25. writer.close();
  26. }
  27. }

4.登录失败处理器

  1. package com.yl.security.handler;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import org.springframework.security.authentication.*;
  4. import org.springframework.security.core.AuthenticationException;
  5. import org.springframework.security.web.authentication.AuthenticationFailureHandler;
  6. import org.springframework.stereotype.Component;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.io.IOException;
  11. import java.io.PrintWriter;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. //登录失败处理器
  15. @Component
  16. public class LoginFailHandler implements AuthenticationFailureHandler {
  17. @Override
  18. public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
  19. response.setContentType("application/json;charset=utf-8");
  20. PrintWriter writer = response.getWriter();
  21. Map<String,Object> map = new HashMap<>();
  22. map.put("code",401);
  23. if (exception instanceof LockedException) {
  24. map.put("msg","账户被锁定");
  25. } else if (exception instanceof BadCredentialsException) {
  26. map.put("msg","用户名或密码错误");
  27. } else if (exception instanceof DisabledException) {
  28. map.put("msg","账户被禁用");
  29. } else if (exception instanceof AccountExpiredException) {
  30. map.put("msg","账户过期");
  31. } else if (exception instanceof CredentialsExpiredException) {
  32. map.put("msg","密码过期");
  33. } else {
  34. map.put("msg","登录异常");
  35. }
  36. writer.write(new ObjectMapper().writeValueAsString(map));
  37. writer.flush();
  38. writer.close();
  39. }
  40. }

5.登出成功处理器

  1. package com.yl.security.handler;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import org.springframework.security.core.Authentication;
  4. import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
  5. import org.springframework.stereotype.Component;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11. import java.util.HashMap;
  12. import java.util.Map;
  13. @Component
  14. public class LogOutSuccessHandler implements LogoutSuccessHandler {
  15. @Override
  16. public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
  17. response.setContentType("application/json;charset=utf-8");
  18. PrintWriter writer = response.getWriter();
  19. Map<String,Object> map = new HashMap<>();
  20. map.put("status",200);
  21. map.put("msg","注销成功");
  22. writer.write(new ObjectMapper().writeValueAsString(map));
  23. writer.flush();
  24. writer.close();
  25. }
  26. }

6.全局方法安全功能

  1. package com.yl.security.service;
  2. import org.springframework.security.access.annotation.Secured;
  3. import org.springframework.security.access.prepost.PreAuthorize;
  4. import org.springframework.stereotype.Service;
  5. @Service
  6. public class MethodService {
  7. @PreAuthorize("hasRole('admin')")
  8. public String admin() {
  9. return "hello admin";
  10. }
  11. @Secured("ROLE_user")
  12. public String user() {
  13. return "hello user";
  14. }
  15. @PreAuthorize("hasAnyRole('admin','user')")
  16. public String hello() {
  17. return "hello hello";
  18. }
  19. }

7.controller

  1. package com.yl.security.controller;
  2. import com.yl.security.service.MethodService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class HelloController {
  8. @Autowired
  9. MethodService methodService;
  10. @GetMapping("/hello")
  11. public String hello() {
  12. return "hello security";
  13. }
  14. @GetMapping("/admin/hello")
  15. public String admin() {
  16. return "hello admin";
  17. }
  18. @GetMapping("/user/hello")
  19. public String user() {
  20. return "hello user";
  21. }
  22. @GetMapping("/login")
  23. public String login() {
  24. return "please login";
  25. }
  26. @GetMapping("/hello1")
  27. public String hello1() {
  28. return methodService.admin();
  29. }
  30. @GetMapping("/hello2")
  31. public String hello2() {
  32. return methodService.user();
  33. }
  34. @GetMapping("/hello3")
  35. public String hello3() {
  36. return methodService.hello();
  37. }
  38. }

8.测试

1.任何请求都要登录

2.登录成功后,会返回相关信息

3.能访问/user/hello

4.但是没权限访问/admin/hello

5.全局方法安全的测试
1)root用户能访问/hello2

2)但是root用户不能访问/hello1

9.配置多个httpsecurityconfig,使用内部类

  1. package com.yl.security.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.core.annotation.Order;
  6. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  9. import org.springframework.security.crypto.password.NoOpPasswordEncoder;
  10. import org.springframework.security.crypto.password.PasswordEncoder;
  11. // 多个httpSecurity的配置,使用静态内部类
  12. @Configuration
  13. public class MultiHttpSecurityConfig {
  14. @Bean
  15. PasswordEncoder passwordEncoder() {
  16. return NoOpPasswordEncoder.getInstance();
  17. }
  18. @Autowired
  19. // 配置静态的用户名和密码
  20. protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  21. auth.inMemoryAuthentication()
  22. .withUser("root").password("111").roles("user")
  23. .and().withUser("admin").password("222").roles("admin");
  24. }
  25. @Configuration
  26. @Order(1) // 设置优先级,数字越小,优先级越高
  27. public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
  28. @Override
  29. protected void configure(HttpSecurity http) throws Exception {
  30. http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasAnyRole("admin");
  31. }
  32. }
  33. @Configuration
  34. public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter {
  35. @Override
  36. protected void configure(HttpSecurity http) throws Exception {
  37. http.authorizeRequests().anyRequest().authenticated()
  38. .and()
  39. .formLogin()
  40. .loginProcessingUrl("/doLogin")
  41. .permitAll()
  42. .and()
  43. .csrf().disable();
  44. }
  45. }
  46. }

相关文章