作者热门文章
- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>security</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>security</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.yl.security.config;
import com.yl.security.handler.LogOutSuccessHandler;
import com.yl.security.handler.LoginFailHandler;
import com.yl.security.handler.LoginSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true) //开启全局方法安全功能
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
LoginSuccessHandler loginSuccessHandler;
@Autowired
LoginFailHandler loginFailHandler;
@Autowired
LogOutSuccessHandler logOutSuccessHandler;
//使用不加密的编码方式
// @Bean
// PasswordEncoder passwordEncoder() {
// return NoOpPasswordEncoder.getInstance();
// }
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
// 基于内存的用户名和密码认证
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
// 密码设置为123
.withUser("root").password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO").roles("user")
.and().withUser("admin").password("$2a$10$O8G0X/sUPAA76MV7U3BwY.3Uo8/QMBcqK678Rwkoz.fowbce.CLtO").roles("admin");
}
//匹配拦截路径,处理器等
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin") //静态配置哪些角色访问才能访问指定路径
// .antMatchers("/user/**").hasAnyRole("admin","user")
.antMatchers("/user/**").access("hasAnyRole('user','admin')")
.anyRequest().authenticated() //其他所有请求登录成功后才能访问
.and()
.formLogin()
.loginProcessingUrl("/doLogin") //登录处理usrl,注意:登录请求为post请求
.loginPage("/login") // 登录的页面
.usernameParameter("username") //登录的用户名参数名
.passwordParameter("password") //登录的密码参数名
.successHandler(loginSuccessHandler) //登录成功后的处理器
.failureHandler(loginFailHandler) //登录失败后的处理器
.permitAll() // 登录接口允许所有人访问
.and()
.logout()
.logoutUrl("/logOut") // 登出接口
.logoutSuccessHandler(logOutSuccessHandler) //登出成功处理器
.and()
.csrf().disable(); //关闭csrf保护
}
}
package com.yl.security.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
//登录成功处理器
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
Map<String,Object> map = new HashMap<>();
map.put("status",200);
map.put("msg",authentication.getPrincipal());
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
}
package com.yl.security.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
//登录失败处理器
@Component
public class LoginFailHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
Map<String,Object> map = new HashMap<>();
map.put("code",401);
if (exception instanceof LockedException) {
map.put("msg","账户被锁定");
} else if (exception instanceof BadCredentialsException) {
map.put("msg","用户名或密码错误");
} else if (exception instanceof DisabledException) {
map.put("msg","账户被禁用");
} else if (exception instanceof AccountExpiredException) {
map.put("msg","账户过期");
} else if (exception instanceof CredentialsExpiredException) {
map.put("msg","密码过期");
} else {
map.put("msg","登录异常");
}
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
}
package com.yl.security.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@Component
public class LogOutSuccessHandler implements LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
Map<String,Object> map = new HashMap<>();
map.put("status",200);
map.put("msg","注销成功");
writer.write(new ObjectMapper().writeValueAsString(map));
writer.flush();
writer.close();
}
}
package com.yl.security.service;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class MethodService {
@PreAuthorize("hasRole('admin')")
public String admin() {
return "hello admin";
}
@Secured("ROLE_user")
public String user() {
return "hello user";
}
@PreAuthorize("hasAnyRole('admin','user')")
public String hello() {
return "hello hello";
}
}
package com.yl.security.controller;
import com.yl.security.service.MethodService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
MethodService methodService;
@GetMapping("/hello")
public String hello() {
return "hello security";
}
@GetMapping("/admin/hello")
public String admin() {
return "hello admin";
}
@GetMapping("/user/hello")
public String user() {
return "hello user";
}
@GetMapping("/login")
public String login() {
return "please login";
}
@GetMapping("/hello1")
public String hello1() {
return methodService.admin();
}
@GetMapping("/hello2")
public String hello2() {
return methodService.user();
}
@GetMapping("/hello3")
public String hello3() {
return methodService.hello();
}
}
1.任何请求都要登录
2.登录成功后,会返回相关信息
3.能访问/user/hello
4.但是没权限访问/admin/hello
5.全局方法安全的测试
1)root用户能访问/hello2
2)但是root用户不能访问/hello1
package com.yl.security.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
// 多个httpSecurity的配置,使用静态内部类
@Configuration
public class MultiHttpSecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Autowired
// 配置静态的用户名和密码
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root").password("111").roles("user")
.and().withUser("admin").password("222").roles("admin");
}
@Configuration
@Order(1) // 设置优先级,数字越小,优先级越高
public static class AdminSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/admin/**").authorizeRequests().anyRequest().hasAnyRole("admin");
}
}
@Configuration
public static class OtherSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/doLogin")
.permitAll()
.and()
.csrf().disable();
}
}
}
安装 npm i -g taro @tarojs/cli taro init myApp创建一个新的项目 编译运行 npm run dev:weapp会在根目录下打包一个dist文件,用开发者工具打开
Apache APISIX 是一个基于 OpenResty 和 Etcd 实现的动态、实时、高性能的 API 网关,目前已经进入 Apache 进行孵化。提供了丰富的流量管理功能,如负载均衡、动
SpringBoot CLI 是spring Boot项目的脚手架工具。而本文的Spring Cloud cli则是基于SpringBoot Client的一个插件,用于支持Cloud相关的组件。
你喜爱的 IDE,现在可用于 Mac。因为在 Visual Studio for Mac 之前,已经有了 Visual Studio Code for Mac,那时候我们还以为 Visual Stu
前面我们学习了本地存储、NFS共享存储,除了这些存储类型之外,还有一个块存储,同样为 Kubernetes 提供块存储的方案有很多,比如 Ceph RBD,今天我们为大家介绍的是 Rancher 开
我是一名优秀的程序员,十分优秀!