SpringSecurity自定義登錄接口的實(shí)現(xiàn)
更新時(shí)間:2025年01月20日 10:28:01 作者:奔跑的大豬蹄子
本文介紹了使用Spring Security實(shí)現(xiàn)自定義登錄接口,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
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{
//請求授權(quán)的規(guī)則
http.authorizeRequests()
//未登錄可以直接訪問
.antMatchers("/loginUser/**").permitAll()
//admin權(quán)限可以訪問(此處可以指定不同的權(quán)限訪問不同的路徑)
.antMatchers("/**").hasAnyAuthority("admin")
.anyRequest().authenticated();// 其他都需要登錄認(rèn)證;
//注銷,開啟了注銷功能,跳到首頁
//http.logout().logoutSuccessUrl("/");
//定制登錄頁(沒有登錄默認(rèn)跳轉(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 "沒有登錄認(rèn)證";
}
@RequestMapping("/signOutSuccess")
public String signOut(){
return "登出成功";
}
@RequestMapping("/fail")
public String fail(){
return "您無權(quán)進(jì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;
/**
* 下兩個(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í)(比如通過用戶名和密碼登錄),Spring Security會(huì)創(chuàng)建一個(gè)UserDetails的實(shí)例,
* 這個(gè)實(shí)例會(huì)包含用戶的認(rèn)證信息,并可以用于后續(xù)的授權(quán)決策。UserDetails接口的主要方法包括:
*
* getUsername(): 返回用戶的用戶名。
* getPassword(): 返回用戶的密碼。注意,密碼通常會(huì)被加密或哈希處理。
* getAuthorities(): 返回一個(gè)Collection,其中包含GrantedAuthority對象,這些對象表示用戶被授予的權(quán)限。
* isAccountNonExpired(): 返回一個(gè)布爾值,指示用戶的賬戶是否未過期。
* isAccountNonLocked(): 返回一個(gè)布爾值,指示用戶的賬戶是否被鎖定。
* isCredentialsNonExpired(): 返回一個(gè)布爾值,指示用戶的憑證(如密碼)是否未過期。
* 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)證未通過,給出提示
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來獲取用戶的詳細(xì)信息,
* 這些詳細(xì)信息將被封裝在一個(gè)UserDetails對象中。
*
* UserDetailsService接口中只有一個(gè)方法:loadUserByUsername
*
* 這個(gè)方法接受一個(gè)用戶名作為參數(shù),并返回一個(gè)UserDetails對象,
* 該對象包含了用戶的詳細(xì)信息,如用戶名、密碼、授權(quán)信息等。
* 如果找不到與給定用戶名對應(yīng)的用戶,該方法應(yīng)該拋出UsernameNotFoundException異常。
*
* 在Spring Security的配置中,需要提供一個(gè)實(shí)現(xiàn)了UserDetailsService接口的bean。
* 這個(gè)bean將負(fù)責(zé)根據(jù)用戶名從數(shù)據(jù)庫或其他用戶存儲(chǔ)中檢索用戶信息,并將其轉(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("用戶名不存在");
}
// 密碼需要加密,否則密碼對比不一致會(huì)認(rèn)證失敗
user.setPwd(passwordEncoder.encode(user.getPwd()));
UserDetail userDetail = new UserDetail();
List<GrantedAuthority> authorities = new ArrayList<>();
// 設(shè)置對應(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 動(dòng)態(tài)生成類和實(shí)例, 并注入方法操作示例
這篇文章主要介紹了Java 動(dòng)態(tài)生成類和實(shí)例, 并注入方法操作,結(jié)合實(shí)例形式分析了Java 動(dòng)態(tài)生成類和實(shí)例以及動(dòng)態(tài)注入相關(guān)操作技巧,需要的朋友可以參考下2020-02-02
Spring Cloud Hystrix 服務(wù)容錯(cuò)保護(hù)的原理實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Hystrix 服務(wù)容錯(cuò)保護(hù)的原理實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
SpringBoot基于Minio實(shí)現(xiàn)分片上傳、斷點(diǎn)續(xù)傳的實(shí)現(xiàn)
本文主要介紹了SpringBoot基于Minio實(shí)現(xiàn)分片上傳、斷點(diǎn)續(xù)傳的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
SpringBoot通過注解監(jiān)測Controller接口的代碼示例
在Spring Boot中,度量指標(biāo)(Metrics)是監(jiān)控和診斷應(yīng)用性能與行為的重要工具,Spring Boot通過集成Micrometer和Spring Boot Actuator,提供了強(qiáng)大的度量指標(biāo)收集與暴露功能,本文介紹了SpringBoot通過注解監(jiān)測Controller接口,需要的朋友可以參考下2024-07-07

