SpringSecurity自定義登錄接口的實現(xiàn)
1.pom依賴
<dependencies>
<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.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.session</groupId>-->
<!--<artifactId>spring-session-data-redis</artifactId>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>redis.clients</groupId>-->
<!--<artifactId>jedis</artifactId>-->
<!--<version>3.6.3</version>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>io.lettuce</groupId>-->
<!--<artifactId>lettuce-core</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<!--</dependency>-->
</dependencies>
2.配置類
package com.example.springsecuritytest.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity//開啟Spring Security的功能
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//鏈式編程
@Override
protected void configure(HttpSecurity http) throws Exception{
//請求授權(quán)的規(guī)則
http.authorizeRequests()
//未登錄可以直接訪問
.antMatchers("/loginUser/**").permitAll()
//admin權(quán)限可以訪問(此處可以指定不同的權(quán)限訪問不同的路徑)
.antMatchers("/**").hasAnyAuthority("admin")
.anyRequest().authenticated();// 其他都需要登錄認證;
//注銷,開啟了注銷功能,跳到首頁
//http.logout().logoutSuccessUrl("/");
//定制登錄頁(沒有登錄默認跳轉(zhuǎn)的路徑)
http.formLogin().loginPage("/loginUser/noLogin");
http.logout().logoutUrl("/signOut").logoutSuccessUrl("/loginUser/signOutSuccess");
http.exceptionHandling().accessDeniedPage("/loginUser/fail");
// 允許跨域請求
http.csrf(csrf -> csrf.disable());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
/**
* 指定加密方式
*/
@Bean
public PasswordEncoder passwordEncoder(){
// 使用BCrypt加密密碼
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
3.controller層
3.1用戶controller
package com.example.springsecuritytest.controller;
import com.example.springsecuritytest.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/loginUser")
public class LoginController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(String username,String pwd){
return userService.login(username,pwd);
}
@RequestMapping("/noLogin")
public String noLogin(){
return "沒有登錄認證";
}
@RequestMapping("/signOutSuccess")
public String signOut(){
return "登出成功";
}
@RequestMapping("/fail")
public String fail(){
return "您無權(quán)進行此操作";
}
}
3.2測試controller
package com.example.springsecuritytest.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 下兩個方法需要登錄認證后,才能訪問
*/
@RestController
public class TestController {
@RequestMapping("/test")
public String test(){
return "success";
}
@PostMapping("/select")
public String select(){
return "查詢成功";
}
}4.entity層
4.1用戶類
package com.example.springsecuritytest.entity;
public class User {
private String username;
private String pwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}4.2 用戶認證信息類
package com.example.springsecuritytest.entity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
/**
* UserDetails是一個核心接口,它代表了一個認證用戶的詳細信息。
* UserDetails接口定義了一些基本的方法,用于獲取用戶的基本信息和授權(quán)信息。
* 當一個用戶進行身份驗證時(比如通過用戶名和密碼登錄),Spring Security會創(chuàng)建一個UserDetails的實例,
* 這個實例會包含用戶的認證信息,并可以用于后續(xù)的授權(quán)決策。UserDetails接口的主要方法包括:
*
* getUsername(): 返回用戶的用戶名。
* getPassword(): 返回用戶的密碼。注意,密碼通常會被加密或哈希處理。
* getAuthorities(): 返回一個Collection,其中包含GrantedAuthority對象,這些對象表示用戶被授予的權(quán)限。
* isAccountNonExpired(): 返回一個布爾值,指示用戶的賬戶是否未過期。
* isAccountNonLocked(): 返回一個布爾值,指示用戶的賬戶是否被鎖定。
* isCredentialsNonExpired(): 返回一個布爾值,指示用戶的憑證(如密碼)是否未過期。
* isEnabled(): 返回一個布爾值,指示用戶賬戶是否啟用。
*/
public class UserDetail implements UserDetails {
private List<GrantedAuthority> authorities;
private User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return user.getPwd();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public void setAuthorities(List<GrantedAuthority> authorities) {
this.authorities = authorities;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
5.service層
5.1用戶登錄service
package com.example.springsecuritytest.service;
public interface UserService {
public String login(String username,String pwd);
}
5.2用戶登錄service實現(xiàn)
package com.example.springsecuritytest.service;
import com.alibaba.fastjson.JSON;
import com.example.springsecuritytest.entity.UserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public String login(String username, String pwd) {
// 用戶認證
//進行用戶認證
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,pwd);
Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//認證未通過,給出提示
if(Objects.isNull(authenticate)){
throw new RuntimeException("登陸失敗!");
}
// 認證成功將用戶信息設置進Security上下文
SecurityContextHolder.getContext().setAuthentication(authenticate);
UserDetail userDetail = (UserDetail)authenticate.getPrincipal();
return JSON.toJSONString(userDetail.getUser());
}
}
5.3 用戶認證service
package com.example.springsecuritytest.service;
import com.example.springsecuritytest.entity.User;
import com.example.springsecuritytest.entity.UserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* UserDetailsService定義了根據(jù)用戶名加載用戶特定數(shù)據(jù)的服務。
* 當Spring Security進行身份驗證時,它會使用UserDetailsService來獲取用戶的詳細信息,
* 這些詳細信息將被封裝在一個UserDetails對象中。
*
* UserDetailsService接口中只有一個方法:loadUserByUsername
*
* 這個方法接受一個用戶名作為參數(shù),并返回一個UserDetails對象,
* 該對象包含了用戶的詳細信息,如用戶名、密碼、授權(quán)信息等。
* 如果找不到與給定用戶名對應的用戶,該方法應該拋出UsernameNotFoundException異常。
*
* 在Spring Security的配置中,需要提供一個實現(xiàn)了UserDetailsService接口的bean。
* 這個bean將負責根據(jù)用戶名從數(shù)據(jù)庫或其他用戶存儲中檢索用戶信息,并將其轉(zhuǎn)換為UserDetails對象。
*
*/
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 模擬根據(jù)用戶名去數(shù)據(jù)庫查詢
User user = getUserByUsername(username);
if(user == null){
throw new UsernameNotFoundException("用戶名不存在");
}
// 密碼需要加密,否則密碼對比不一致會認證失敗
user.setPwd(passwordEncoder.encode(user.getPwd()));
UserDetail userDetail = new UserDetail();
List<GrantedAuthority> authorities = new ArrayList<>();
// 設置對應權(quán)限
authorities.add(()-> "admin");
userDetail.setAuthorities(authorities);
userDetail.setUser(user);
return userDetail;
}
private User getUserByUsername(String username){
if("ttz".equals(username)){
User user = new User();
user.setUsername("ttz");
user.setPwd("980422");
return user;
}
return null;
}
}到此這篇關于SpringSecurity自定義登錄接口的實現(xiàn)的文章就介紹到這了,更多相關SpringSecurity自定義登錄接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java idea如何根據(jù)請求路徑url自動找到對應controller方法插件
這篇文章主要介紹了java idea如何根據(jù)請求路徑url自動找到對應controller方法插件,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring @RestController注解組合實現(xiàn)方法解析
這篇文章主要介紹了Spring @RestController注解組合實現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
解決Spring Cloud中Feign/Ribbon第一次請求失敗的方法
這篇文章主要給大家介紹了關于解決Spring Cloud中Feign/Ribbon第一次請求失敗的方法,文中給出了三種解決的方法,大家可以根據(jù)需要選擇對應的方法,需要的朋友們下面來一起看看吧。2017-02-02
教你用Springboot實現(xiàn)攔截器獲取header內(nèi)容
項目中遇到一個需求,對接上游系統(tǒng)是涉及到需要增加請求頭,請求頭的信息是動態(tài)獲取的,需要動態(tài)從下游拿到之后轉(zhuǎn)給上游,文中非常詳細的介紹了該需求的實現(xiàn),需要的朋友可以參考下2021-05-05
詳解JDK中ExecutorService與Callable和Future對線程的支持
這篇文章主要介紹了詳解JDK中ExecutorService與Callable和Future對線程的支持的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09
SpringCloud?Eureka服務注冊中心應用入門詳解
這篇文章主要介紹了Spring?Cloud?Eureka服務注冊中心入門流程分析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
SpringBoot+Vue3整合SSE實現(xiàn)實時消息推送
這篇文章主要為大家詳細介紹了SpringBoot+Vue3整合SSE實現(xiàn)實時消息推送的相關方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2026-03-03
SpringBoot中IP白名單控制實現(xiàn)限制接口訪問
IP白名單是一種網(wǎng)絡安全機制,通過預設允許訪問的IP地址列表實現(xiàn)對請求來源的精確控制,在Spring Boot中實現(xiàn)IP白名單有多種技術方案,下面就拉介紹一下,感興趣的可以了解一下2025-07-07

