[英]How exactly works Spring Security configuration in this Spring Boot project?
我不太喜歡Spring Security 。 我正在一個Spring Boot項目(實現一些REST Web服務)中,其他人已經實現了Spring Security來執行身份驗證。 看起來不錯,但我對它的工作原理(體系結構)有些懷疑。
所以基本上我有以下課程:
1) 用戶是我代表用戶的模型類 :
@Entity
@Table(name = "user",
uniqueConstraints = {
@UniqueConstraint(columnNames = {"email","username"})
})
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//@Pattern(regexp="\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b",flags = Pattern.Flag.CASE_INSENSITIVE)
@Column(name="email", unique=true,nullable=false)
private String email;
@NotNull
@Column(name="registration_date",nullable=false)
private Date registration_date;
@NotBlank
@Column(name="username",nullable = false,unique=true)
private String username;
@NotBlank
@Column(name="password",nullable = false)
private String password;
@Column(name="enabled", nullable = false)
private boolean enabled;
@ManyToMany
@JoinTable(name = "user_user_roles", joinColumns = {
@JoinColumn(name = "id_user", updatable = true) },
inverseJoinColumns = { @JoinColumn(name = "id_roles",
updatable = true)},
uniqueConstraints={@UniqueConstraint(columnNames = {"id_user","id_roles"})}
)
@Cascade({CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.PERSIST,
CascadeType.SAVE_UPDATE})
private List<UserRole> userRoles;
// CONSTRUCTOR, GETTER AND SETTER METHODS
}
這是一個休眠類,提供聯接包含關聯到特定的用戶(我覺得ROLE_ADMIN,ROLE_USER,etcetc)用戶ROOL列表中user_user_roles數據庫表
2)然后我有CustomUserDetails類,該類擴展了User並實現了Spring Security UserDetails接口。
因此,這意味着它將包含與特定用戶有關的所有信息(其中包括與此用戶相關聯的角色),並實現在UserDetails接口中聲明的所有方法。
public class CustomUserDetails extends User implements UserDetails {
private static final long serialVersionUID = 1L;
public CustomUserDetails(User user){
super(user);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(UserRole role : this.getUserRoles() ){
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getName());
authorities.add(grantedAuthority);
}
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public String getUsername() {
return super.getUsername();
}
}
在我看來,該類代表了Spring應用程序與Spring Security之間的橋梁(類似的東西帶有與特定用戶有關的角色信息,是嗎?)。
在此類中,與用戶角色列表有關的信息包含在擴展GrantedAuthority的通用對象的集合中。
我認為GrantedAuthority對象表示用戶的角色(實際上是由role.getName()構建的 ,該字符串是表示當前用戶角色的字符串)。 這個推理正確嗎?
基本上,以前的實現只返回與特定用戶相關的GrantedAuthority的集合,對嗎?
3)實現Spring Security UserDetailsService接口的CustomUserDetailsService類:
@Transactional
@Service("customUserDetailsService")
public class CustomUserDetailsService implements UserDetailsService{
@Autowired
private UserDAO userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDao.findByUsername(username);
if(user == null){
throw new UsernameNotFoundException("No user present with username: "+username);
}else{
return new CustomUserDetails(user);
}
}
}
基本上,這是一個僅實現loadUserByUsername(String username))方法的服務,該方法執行以下操作:
首先檢索與用戶(一個User對象)有關的信息,包括他的角色列表 ( List userRoles )。
然后,使用此User對象構建先前的CustomUserDetails,該CustomUserDetails用於檢索與該用戶相關的GrantedAuthority的集合。
所有這些推理都正確嗎?
然后我還有這個WebSecurityConfig ,我認為它代表了Spring Security的配置:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = CustomUserDetailsService.class)
@EnableAutoConfiguration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
這對我來說太晦澀了。 到底是什么?
據我了解,它通過** @ EnableWebSecurity **來啟用REST Web服務安全性。
但是,為什么要自動裝配UserDetailsService Bean?
究竟該空的configure()方法是什么呢?
您的推論是正確的。
Spring-security要求您創建一個實現UserDetailsService的服務。 它期望服務具有loadUserByUsername方法,該方法返回用戶對象(需要實現Spring的User類)。 該用戶實例用於獲取權限,以便您可以限制對某些URL的訪問。 即,您可以將URL訪問映射到具有特定權限的用戶。
就空方法configure()而言,它用於url的身份驗證和授權(如上所述)以及其他一些事情。 實際上,就安全性而言,這是最靈活,最強大的方法。
我項目的config方法如下所示:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/","/static/**").permitAll()
.mvcMatchers("/admin").access("hasAuthority('ROLE_ADMIN')")
.mvcMatchers("/employees").access("hasAuthority('ROLE_STAFF')")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.logout().logoutSuccessUrl("/")
.and()
.headers().contentSecurityPolicy("default-src 'self' " +
"https://ajax.googleapis.com " +
"https://cdnjs.cloudfare.com " +
"style-src 'self' 'unsafe-inline' ");
}
上面的例子
要了解有關所有春季安全性功能的更多信息,我強烈建議您使用這些資源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.