我創建了一個非常簡單的站點,每個人都可以訪問 /about,經過身份驗證的用戶可以訪問 /profile 并且只有具有“ADMIN”角色的用戶可以訪問。我添加了一個“管理員”用戶DBInit.java然后我嘗試訪問 /admin 并獲得一個 http 基本登錄表單。我輸入 adminEmail 作為登錄名,輸入 admin123 作為密碼,但我無法訪問 /admin 頁面。所以我的代碼中某處有錯誤,我可以看到它。那么錯誤在哪里以及如何擺脫它?如果我在記憶體中使用身份驗證,一切正常。
// In memory authentication
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
// auth.authenticationProvider(authenticationProvider());
auth.inMemoryAuthentication()
.withUser("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN");
}
安全組態檔
import Onlinestore.service.UserPrincipalDetailsService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.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
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
{
private UserPrincipalDetailsService userPrincipalDetailsService;
public SecurityConfiguration(UserPrincipalDetailsService userPrincipalDetailsService)
{
this.userPrincipalDetailsService = userPrincipalDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
{
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/about").permitAll()
.antMatchers("/profile").authenticated()
.antMatchers("/admin/**").hasRole("ADMIN")
.and()
.httpBasic();
}
@Bean
DaoAuthenticationProvider authenticationProvider()
{
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userPrincipalDetailsService);
return daoAuthenticationProvider;
}
@Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
}
用戶.java
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
@Entity(name = "user")
@Table(name = "users")
@NoArgsConstructor
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Getter
@Setter
private int id;
@Getter
@Setter
@Column(nullable = false)
private String name;
@Getter
@Setter
private String surname;
@Getter
@Setter
@Column(nullable = false)
private String password;
@Getter
@Setter
@Column(name = "telephone_number", nullable = false)
private String telephoneNumber;
@Getter
@Setter
@Column(unique = true)
private String email;
@Getter
@Setter
private String country;
@Getter
@Setter
private String address;
@Getter
@Setter
// delimiter = ";"
private String roleNames;
public User(String name, String surname, String password, String telephoneNumber, String email, String country, String address, String roleNames)
{
this.name = name;
this.surname = surname;
this.password = password;
this.telephoneNumber = telephoneNumber;
this.email = email;
this.country = country;
this.address = address;
this.roleNames = roleNames;
}
}
用戶主體.java
import Onlinestore.entity.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class UserPrincipal implements UserDetails
{
private User user;
public UserPrincipal(User user)
{
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities()
{
String[] roles = user.getRoleNames().split(";");
List<GrantedAuthority> authorities = new ArrayList<>();
for (String role : roles)
{
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
@Override
public String getPassword()
{
return user.getPassword();
}
@Override
public String getUsername()
{
return user.getName();
}
@Override
public boolean isAccountNonExpired()
{
return false;
}
@Override
public boolean isAccountNonLocked()
{
return false;
}
@Override
public boolean isCredentialsNonExpired()
{
return false;
}
@Override
public boolean isEnabled()
{
return false;
}
}
UserPrincipalDetailsS??ervice.java
import Onlinestore.entity.User;
import Onlinestore.repository.UserRepository;
import Onlinestore.security.UserPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class UserPrincipalDetailsService implements UserDetailsService
{
private UserRepository userRepository;
public UserPrincipalDetailsService(UserRepository userRepository)
{
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user = userRepository.findUserByEmail(username);
return new UserPrincipal(user);
}
}
資料庫初始化程式
import Onlinestore.entity.User;
import Onlinestore.repository.UserRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class DBInit implements CommandLineRunner
{
private UserRepository userRepository;
private PasswordEncoder passwordEncoder;
public DBInit(UserRepository userRepository, PasswordEncoder passwordEncoder)
{
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@Override
public void run(String[] args)
{
User user1 = new User("admin", "admin", passwordEncoder.encode("admin123"),
" 111111111", "adminEmail", "country1", "address1", "ADMIN");
List<User> users = Arrays.asList(user1);
userRepository.saveAll(users);
}
}
用戶庫
import Onlinestore.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Integer>
{
User findUserByEmail(String email);
}
uj5u.com熱心網友回復:
記憶體中的身份驗證需要配置中的硬編碼憑據。它不會從資料庫中提取憑據。
如果您想使用資料庫中的憑據,那么您的其余設定乍一看還不錯。嘗試
httpSecurity
.authorizeRequests()
.antMatchers(PUBLIC_MATCHERS)
.permitAll()
.anyRequest()
.authenticated();
PUBLIC_MATCHERS如果您有這樣的東西,則不需要身份驗證的端點陣列在哪里。
uj5u.com熱心網友回復:
我發現了所有錯誤。
- 在課堂上,
UserPrincipal我不得不重寫這個方法和return true,但不是return false。我認為當我return falseSpring Security 認為用戶被阻止、過期、禁用等并阻止身份驗證時。這但也有一些錯誤和應用程式還沒有像我想要的那樣作業。方法的正確實施UserPrincipal
@Override
public boolean isAccountNonExpired()
{
return true;
}
@Override
public boolean isAccountNonLocked()
{
return true;
}
@Override
public boolean isCredentialsNonExpired()
{
return true;
}
@Override
public boolean isEnabled()
{
return true;
}
- 在課堂上
UserPrincipal,我不得不return user.getEmail()在getUserName(),但不是return user.getName()因為我使用電子郵件作為驗證用戶名。
@Override
public String getUsername()
{
return user.getEmail();
}
- 在
UserPrincipalDetailsService課堂上,當沒有具有此類用戶名的用戶時,loadUserByUsername()我不得不拋出例外UsernameNotFoundException
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
User user = userRepository.findUserByEmail(username);
if (user == null)
{
throw new UsernameNotFoundException("user not found");
}
return new UserPrincipal(user);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/398991.html
