SpringSecurity自定義登錄接口的實(shí)現(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 {
//鏈?zhǔn)骄幊?
@Override
protected void configure(HttpSecurity http) throws Exception{
//請(qǐng)求授權(quán)的規(guī)則
http.authorizeRequests()
//未登錄可以直接訪問
.antMatchers("/loginUser/**").permitAll()
//admin權(quán)限可以訪問(此處可以指定不同的權(quán)限訪問不同的路徑)
.antMatchers("/**").hasAnyAuthority("admin")
.anyRequest().authenticated();// 其他都需要登錄認(rèn)證;
//注銷,開啟了注銷功能,跳到首頁(yè)
//http.logout().logoutSuccessUrl("/");
//定制登錄頁(yè)(沒有登錄默認(rèn)跳轉(zhuǎn)的路徑)
http.formLogin().loginPage("/loginUser/noLogin");
http.logout().logoutUrl("/signOut").logoutSuccessUrl("/loginUser/signOutSuccess");
http.exceptionHandling().accessDeniedPage("/loginUser/fail");
// 允許跨域請(qǐng)求
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 "沒有登錄認(rèn)證";
}
@RequestMapping("/signOutSuccess")
public String signOut(){
return "登出成功";
}
@RequestMapping("/fail")
public String fail(){
return "您無(wú)權(quán)進(jìn)行此操作";
}
}
3.2測(cè)試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;
/**
* 下兩個(gè)方法需要登錄認(rèn)證后,才能訪問
*/
@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 用戶認(rèn)證信息類
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是一個(gè)核心接口,它代表了一個(gè)認(rèn)證用戶的詳細(xì)信息。
* UserDetails接口定義了一些基本的方法,用于獲取用戶的基本信息和授權(quán)信息。
* 當(dāng)一個(gè)用戶進(jìn)行身份驗(yàn)證時(shí)(比如通過(guò)用戶名和密碼登錄),Spring Security會(huì)創(chuàng)建一個(gè)UserDetails的實(shí)例,
* 這個(gè)實(shí)例會(huì)包含用戶的認(rèn)證信息,并可以用于后續(xù)的授權(quán)決策。UserDetails接口的主要方法包括:
*
* getUsername(): 返回用戶的用戶名。
* getPassword(): 返回用戶的密碼。注意,密碼通常會(huì)被加密或哈希處理。
* getAuthorities(): 返回一個(gè)Collection,其中包含GrantedAuthority對(duì)象,這些對(duì)象表示用戶被授予的權(quán)限。
* isAccountNonExpired(): 返回一個(gè)布爾值,指示用戶的賬戶是否未過(guò)期。
* isAccountNonLocked(): 返回一個(gè)布爾值,指示用戶的賬戶是否被鎖定。
* isCredentialsNonExpired(): 返回一個(gè)布爾值,指示用戶的憑證(如密碼)是否未過(guò)期。
* isEnabled(): 返回一個(gè)布爾值,指示用戶賬戶是否啟用。
*/
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實(shí)現(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) {
// 用戶認(rèn)證
//進(jìn)行用戶認(rèn)證
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,pwd);
Authentication authenticate = authenticationManager.authenticate(authenticationToken);
//認(rèn)證未通過(guò),給出提示
if(Objects.isNull(authenticate)){
throw new RuntimeException("登陸失??!");
}
// 認(rèn)證成功將用戶信息設(shè)置進(jìn)Security上下文
SecurityContextHolder.getContext().setAuthentication(authenticate);
UserDetail userDetail = (UserDetail)authenticate.getPrincipal();
return JSON.toJSONString(userDetail.getUser());
}
}
5.3 用戶認(rèn)證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ù)的服務(wù)。
* 當(dāng)Spring Security進(jìn)行身份驗(yàn)證時(shí),它會(huì)使用UserDetailsService來(lái)獲取用戶的詳細(xì)信息,
* 這些詳細(xì)信息將被封裝在一個(gè)UserDetails對(duì)象中。
*
* UserDetailsService接口中只有一個(gè)方法:loadUserByUsername
*
* 這個(gè)方法接受一個(gè)用戶名作為參數(shù),并返回一個(gè)UserDetails對(duì)象,
* 該對(duì)象包含了用戶的詳細(xì)信息,如用戶名、密碼、授權(quán)信息等。
* 如果找不到與給定用戶名對(duì)應(yīng)的用戶,該方法應(yīng)該拋出UsernameNotFoundException異常。
*
* 在Spring Security的配置中,需要提供一個(gè)實(shí)現(xiàn)了UserDetailsService接口的bean。
* 這個(gè)bean將負(fù)責(zé)根據(jù)用戶名從數(shù)據(jù)庫(kù)或其他用戶存儲(chǔ)中檢索用戶信息,并將其轉(zhuǎn)換為UserDetails對(duì)象。
*
*/
@Service
public class UserDetailServiceImpl implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 模擬根據(jù)用戶名去數(shù)據(jù)庫(kù)查詢
User user = getUserByUsername(username);
if(user == null){
throw new UsernameNotFoundException("用戶名不存在");
}
// 密碼需要加密,否則密碼對(duì)比不一致會(huì)認(rèn)證失敗
user.setPwd(passwordEncoder.encode(user.getPwd()));
UserDetail userDetail = new UserDetail();
List<GrantedAuthority> authorities = new ArrayList<>();
// 設(shè)置對(duì)應(yīng)權(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;
}
}到此這篇關(guān)于SpringSecurity自定義登錄接口的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringSecurity自定義登錄接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java idea如何根據(jù)請(qǐng)求路徑url自動(dòng)找到對(duì)應(yīng)controller方法插件
這篇文章主要介紹了java idea如何根據(jù)請(qǐng)求路徑url自動(dòng)找到對(duì)應(yīng)controller方法插件,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring @RestController注解組合實(shí)現(xiàn)方法解析
這篇文章主要介紹了Spring @RestController注解組合實(shí)現(xiàn)方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Java集合遍歷全指南(迭代器&增強(qiáng)for及列表迭代器)
本文詳盡介紹了Java集合遍歷的5種方式:迭代器、增強(qiáng)for、列表迭代器、普通for及Lambda表達(dá)式,通過(guò)代碼示例和原理解析,幫助讀者徹底掌握集合遍歷的核心知識(shí),避免常見錯(cuò)誤如并發(fā)修改異常和指針復(fù)位問題,適合Java初學(xué)者及面試復(fù)習(xí),需要的朋友可以參考下2026-02-02
解決Spring Cloud中Feign/Ribbon第一次請(qǐng)求失敗的方法
這篇文章主要給大家介紹了關(guān)于解決Spring Cloud中Feign/Ribbon第一次請(qǐng)求失敗的方法,文中給出了三種解決的方法,大家可以根據(jù)需要選擇對(duì)應(yīng)的方法,需要的朋友們下面來(lái)一起看看吧。2017-02-02
教你用Springboot實(shí)現(xiàn)攔截器獲取header內(nèi)容
項(xiàng)目中遇到一個(gè)需求,對(duì)接上游系統(tǒng)是涉及到需要增加請(qǐng)求頭,請(qǐng)求頭的信息是動(dòng)態(tài)獲取的,需要?jiǎng)討B(tài)從下游拿到之后轉(zhuǎn)給上游,文中非常詳細(xì)的介紹了該需求的實(shí)現(xiàn),需要的朋友可以參考下2021-05-05
詳解JDK中ExecutorService與Callable和Future對(duì)線程的支持
這篇文章主要介紹了詳解JDK中ExecutorService與Callable和Future對(duì)線程的支持的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09
SpringCloud?Eureka服務(wù)注冊(cè)中心應(yīng)用入門詳解
這篇文章主要介紹了Spring?Cloud?Eureka服務(wù)注冊(cè)中心入門流程分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
SpringBoot+Vue3整合SSE實(shí)現(xiàn)實(shí)時(shí)消息推送
這篇文章主要為大家詳細(xì)介紹了SpringBoot+Vue3整合SSE實(shí)現(xiàn)實(shí)時(shí)消息推送的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2026-03-03
SpringBoot中IP白名單控制實(shí)現(xiàn)限制接口訪問
IP白名單是一種網(wǎng)絡(luò)安全機(jī)制,通過(guò)預(yù)設(shè)允許訪問的IP地址列表實(shí)現(xiàn)對(duì)請(qǐng)求來(lái)源的精確控制,在Spring Boot中實(shí)現(xiàn)IP白名單有多種技術(shù)方案,下面就拉介紹一下,感興趣的可以了解一下2025-07-07

