這是我的用戶詳細資訊物件
2022-10-19 07:35:58.143 INFO 24580 --- [nio-8081-exec-6] csjwt.api.filter.JwtFilter:用戶詳細資訊:org.springframework.security.core.userdetails.User [用戶名=502553205 , Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[Authority(id=1, authority=Engine Line Tracker, description=Engine Line Tracker), Authority(id= 2, authority=Pin a Card, description=Pin a Card), Authority(id=5, authority=Project Plan, description=Project Plan), Authority(id=4, authority=Scorecard, description=Scorecard), Authority(id =6, authority=Search, description=Search), authority(id=3, authority=Upload/Download/Edit, description=Upload/Download/Edit)]]
我的端點是
@GetMapping
@RolesAllowed({"Scorecard"})
public List<User> list(){
return userRepository.findAll();
}
這在我洗掉 @RolesAllowed 但不從我的用戶物件中獲取角色時運行。我在放置角色方面做錯了嗎?
是的,它已啟用
package com.springimplant.jwt.api.config;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.springimplant.jwt.api.filter.JwtFilter;
import com.springimplant.jwt.api.service.CustomUserDetailService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = false,
securedEnabled = false,
jsr250Enabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailService userDetailService;
@Autowired
private JwtFilter filter;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean(name= BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService).passwordEncoder(new BCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/authenticate").permitAll()
.anyRequest().authenticated().and()
.exceptionHandling().authenticationEntryPoint(((request, response, authException) -> {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
authException.getMessage();
} )).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(filter,UsernamePasswordAuthenticationFilter.class);
}
}
我的權威課程如下
package com.springimplant.jwt.api.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "authorties")
public class Authority implements GrantedAuthority{
// private static final long serialVersionUID = 1L;
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
@Id
@SequenceGenerator(name = "authorties_seq", sequenceName = "authorties_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "authorties_seq")
private Long id;
@Column(name="authority")
private String authority;
@Column(name="description")
private String description;
@Override
public String getAuthority() {
return authority;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Authority) {
return this.authority.equals(((Authority) obj).authority);
}
return false;
}
@Override
public int hashCode() {
return this.authority.hashCode();
}
@Override
public String toString() {
return this.authority;
}
}
uj5u.com熱心網友回復:
首先,我認為讓角色名稱簡短而沒有空格、斜杠和下劃線是一個很好的做法。您的串列可能如下所示:SCORECARD、PROJECT_PLAN、UPLOAD_DOWNLOAD_EDIT。
要使用@RolesAllowed,您必須確保在@EnableGlobalMethodSecurity 中啟用了jsr250:
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {}
或者對于 Spring 5.6 及更高版本,您可以將 @EnableGlobalMethodSecurity 注釋替換為 @EnableMethodSecurity
這允許您使用@Secured、@PreAuthorized、@PostAuthorized 和@RolesAllowed。
有關它的更多資訊在官方檔案中
===== UPD =====
現在,當您提供更多詳細資訊時,我猜您錯過了一件重要的事情:角色!= 權限。默認情況下,Spring 中的角色具有 ROLE_ 前綴。如果您沒有在任何地方替換它,它只會嘗試將 ROLE_Scorecard 與記分卡進行比較。
要洗掉該前綴,您可以在配置中執行此操作:
@Bean
fun grantedAuthorityDefaults(): GrantedAuthorityDefaults? {
return GrantedAuthorityDefaults("") // Remove the ROLE_ prefix
}
=== UPD2 ===
哈,在我寫更新的時候,Ken Chan 又提出了一個好點。如果您要使用權威方法,那么 Ken Chan 的 hasAuthority() 會更合適。
uj5u.com熱心網友回復:
一個問題是,默認情況下@RolesAllowed會期望用戶具有以前綴開頭的權限。ROLE_所以@RolesAllowed({"Scorecard"})會期望用戶有權限ROLE_Scorecard。但是現在由于用戶只有權限Scorecard,它不匹配ROLE_Scorecard,因此被拒絕訪問。
簡單的解決方法是更改??使用@PreAuthorize:
@GetMapping
@PreAuthorize("hasAuthority('Scorecard')")
public List<User> list(){
return userRepository.findAll();
}
它將直接檢查用戶是否具有Scorecard任何前綴行為的權限。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/518067.html
標籤:春天弹簧靴弹簧安全角色
