<?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();
}
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41359273/article/details/123224441
内容来源于网络,如有侵权,请联系作者删除!