✨ 添加登录测试
This commit is contained in:
parent
46ed909158
commit
44dee07956
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.3.13</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.mall</groupId>
|
<groupId>com.mall</groupId>
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.core.userdetails.User;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||||
|
|
||||||
|
@ -26,10 +25,10 @@ public class DefaultSecurityConfig {
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(UserDetailsService.class)
|
@ConditionalOnMissingBean(UserDetailsService.class)
|
||||||
InMemoryUserDetailsManager inMemoryUserDetailsManager() {
|
InMemoryUserDetailsManager inMemoryUserDetailsManager(PasswordEncoder passwordEncoder) {
|
||||||
String generatedPassword = PasswordEncoderFactories.createDelegatingPasswordEncoder()
|
|
||||||
.encode("123456");
|
String generatedPassword = passwordEncoder.encode("123456");
|
||||||
return new InMemoryUserDetailsManager(User.withUsername("user")
|
return new InMemoryUserDetailsManager(User.withUsername("bunny")
|
||||||
.password(generatedPassword).roles("USER").build());
|
.password(generatedPassword).roles("USER").build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +45,8 @@ public class DefaultSecurityConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
|
public AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
|
||||||
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(userDetailsService);
|
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
|
||||||
|
authenticationProvider.setUserDetailsService(userDetailsService);
|
||||||
authenticationProvider.setPasswordEncoder(passwordEncoder);
|
authenticationProvider.setPasswordEncoder(passwordEncoder);
|
||||||
|
|
||||||
return new ProviderManager(authenticationProvider);
|
return new ProviderManager(authenticationProvider);
|
||||||
|
|
|
@ -41,4 +41,14 @@ public class Knife4jConfig {
|
||||||
public GroupedOpenApi all() {
|
public GroupedOpenApi all() {
|
||||||
return GroupedOpenApi.builder().group("全部请求接口").pathsToMatch("/api/**").build();
|
return GroupedOpenApi.builder().group("全部请求接口").pathsToMatch("/api/**").build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi system() {
|
||||||
|
return GroupedOpenApi.builder().group("系统请求接口").pathsToMatch("/api/system/**").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi security() {
|
||||||
|
return GroupedOpenApi.builder().group("security接口").pathsToMatch("/api/security/**").build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package com.spring.config;
|
package com.spring.config;
|
||||||
|
|
||||||
|
import com.spring.config.handler.SecurityAccessDeniedHandler;
|
||||||
|
import com.spring.config.handler.SecurityAuthenticationEntryPoint;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.Customizer;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.provisioning.JdbcUserDetailsManager;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfiguration {
|
public class SecurityConfiguration {
|
||||||
|
@ -15,11 +21,29 @@ public class SecurityConfiguration {
|
||||||
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
|
HttpSessionRequestCache requestCache = new HttpSessionRequestCache();
|
||||||
http
|
http
|
||||||
.httpBasic(Customizer.withDefaults())
|
|
||||||
.requestCache(cache -> cache.requestCache(requestCache))
|
.requestCache(cache -> cache.requestCache(requestCache))
|
||||||
|
// 如果禁用登录页会有弹窗形式的登录
|
||||||
|
.formLogin(AbstractHttpConfigurer::disable)
|
||||||
|
// 开启打开默认页会让登录
|
||||||
|
// .formLogin(Customizer.withDefaults())
|
||||||
|
.formLogin(AbstractHttpConfigurer::disable)
|
||||||
|
.authorizeHttpRequests((authorize) -> authorize
|
||||||
|
.requestMatchers("/", "/*/*/login").permitAll()
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
)
|
||||||
|
.exceptionHandling(configurer -> {
|
||||||
|
// 访问拒绝处理器
|
||||||
|
configurer.accessDeniedHandler(new SecurityAccessDeniedHandler());
|
||||||
|
// 认证入口点
|
||||||
|
configurer.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
|
||||||
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public UserDetailsService userDetailsService(DataSource dataSource) {
|
||||||
|
return new JdbcUserDetailsManager(dataSource);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.spring.config.handler;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.spring.domain.vo.result.Result;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {
|
||||||
|
@Override
|
||||||
|
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
|
||||||
|
log.error("CustomerAccessDeniedHandler:{}", accessDeniedException.getLocalizedMessage());
|
||||||
|
|
||||||
|
Result<Object> result = Result.error(accessDeniedException.getMessage());
|
||||||
|
|
||||||
|
Object json = JSON.toJSON(result);
|
||||||
|
|
||||||
|
// 返回响应
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().println(json);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.spring.config.handler;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.spring.domain.vo.result.Result;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
log.error("CustomerAccessDeniedHandler:{}", authException.getLocalizedMessage());
|
||||||
|
|
||||||
|
Result<Object> result = Result.error(authException.getMessage());
|
||||||
|
|
||||||
|
Object json = JSON.toJSON(result);
|
||||||
|
|
||||||
|
// 返回响应
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().println(json);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.spring.controller.security;
|
||||||
|
|
||||||
|
import com.spring.domain.dto.security.LoginRequest;
|
||||||
|
import com.spring.domain.vo.result.Result;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Tag(name = "Login接口", description = "登录接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/security")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LoginController {
|
||||||
|
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
|
@Operation(summary = "登录接口", description = "系统登录接口")
|
||||||
|
@PostMapping("login")
|
||||||
|
public Result<Authentication> login(@RequestBody LoginRequest loginRequest) {
|
||||||
|
String username = loginRequest.getUsername();
|
||||||
|
String password = loginRequest.getPassword();
|
||||||
|
|
||||||
|
Authentication authenticationRequest = UsernamePasswordAuthenticationToken.unauthenticated(username, password);
|
||||||
|
|
||||||
|
Authentication authenticationResponse = authenticationManager.authenticate(authenticationRequest);
|
||||||
|
return Result.success(authenticationResponse);
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ public class MessageReceivedController {
|
||||||
|
|
||||||
private final MessageReceivedService messageReceivedService;
|
private final MessageReceivedService messageReceivedService;
|
||||||
|
|
||||||
@Operation(summary = "分页查询", description = "分页")
|
@Operation(summary = "消息接受分页查询", description = "消息接受分页")
|
||||||
@GetMapping("{page}/{limit}")
|
@GetMapping("{page}/{limit}")
|
||||||
public Result<PageResult<MessageReceivedVo>> getMessageReceivedPage(
|
public Result<PageResult<MessageReceivedVo>> getMessageReceivedPage(
|
||||||
@Parameter(name = "page", description = "当前页", required = true)
|
@Parameter(name = "page", description = "当前页", required = true)
|
||||||
|
@ -46,21 +46,21 @@ public class MessageReceivedController {
|
||||||
return Result.success(pageResult);
|
return Result.success(pageResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "添加", description = "添加")
|
@Operation(summary = "添加", description = "添加消息接受")
|
||||||
@PostMapping()
|
@PostMapping()
|
||||||
public Result<String> addMessageReceived(@Valid @RequestBody MessageReceivedDto dto) {
|
public Result<String> addMessageReceived(@Valid @RequestBody MessageReceivedDto dto) {
|
||||||
messageReceivedService.addMessageReceived(dto);
|
messageReceivedService.addMessageReceived(dto);
|
||||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "更新", description = "更新")
|
@Operation(summary = "更新", description = "更新消息接受")
|
||||||
@PutMapping()
|
@PutMapping()
|
||||||
public Result<String> updateMessageReceived(@Valid @RequestBody MessageReceivedDto dto) {
|
public Result<String> updateMessageReceived(@Valid @RequestBody MessageReceivedDto dto) {
|
||||||
messageReceivedService.updateMessageReceived(dto);
|
messageReceivedService.updateMessageReceived(dto);
|
||||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "删除", description = "删除")
|
@Operation(summary = "删除", description = "删除消息接受")
|
||||||
@DeleteMapping()
|
@DeleteMapping()
|
||||||
public Result<String> deleteMessageReceived(@RequestBody List<Long> ids) {
|
public Result<String> deleteMessageReceived(@RequestBody List<Long> ids) {
|
||||||
messageReceivedService.deleteMessageReceived(ids);
|
messageReceivedService.deleteMessageReceived(ids);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.spring.domain.dto.security;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Schema(name = "LoginRequest", title = "LoginRequest登录参数", description = "登录请求参数")
|
||||||
|
public class LoginRequest {
|
||||||
|
|
||||||
|
@Schema(name = "username", title = "用户名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(name = "password", description = "密码")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package com.spring.service.security;
|
||||||
|
|
||||||
|
public interface LoginService {
|
||||||
|
}
|
|
@ -395,7 +395,7 @@
|
||||||
<p>学习最强大的Java安全框架,保护您的应用程序免受现代安全威胁。Spring Security
|
<p>学习最强大的Java安全框架,保护您的应用程序免受现代安全威胁。Spring Security
|
||||||
6提供了全面的身份验证和授权功能,让您的应用安全无忧。</p>
|
6提供了全面的身份验证和授权功能,让您的应用安全无忧。</p>
|
||||||
<div>
|
<div>
|
||||||
<a class="btn" href="#docs" target="_blank">开始学习</a>
|
<a class="btn" href="#docs">开始学习</a>
|
||||||
<a class="btn btn-outline" href="/doc.html" target="_blank">查看API文档</a>
|
<a class="btn btn-outline" href="/doc.html" target="_blank">查看API文档</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue