我不太喜歡 Spring Security 和 JWT 令牌,我對我正在從事的專案有以下疑問。
基本上我有這個包含我的 Spring Security 配置的SecurityConfiguration類,正如你所看到的,它旨在處理 JWT 令牌:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("customUserDetailsService")
private UserDetailsService userDetailsService;
@Autowired
private JwtConfig jwtConfig;
@Autowired
private JwtTokenUtil jwtTokenUtil;
private static final String[] USER_MATCHER = { "/api/user/email/**"};
private static final String[] ADMIN_MATCHER = { "/api/users/email/**"};
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
/*
* NOTE:
* Using hasRole expects the authority names to start with 'ROLE_' prefix
* Instead, we use hasAuthority as we can use the names as it is
*/
http.csrf().disable()
.authorizeRequests()
//.antMatchers(USER_MATCHER).hasAnyAuthority("USER")
.antMatchers(USER_MATCHER).hasAnyAuthority("CLIENT")
.antMatchers(ADMIN_MATCHER).hasAnyAuthority("ADMIN")
.antMatchers("/api/users/test").authenticated()
.antMatchers(HttpMethod.POST, jwtConfig.getUri()).permitAll()
.anyRequest().denyAll()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(
new TokenVerificationFilter(authenticationManager(), jwtConfig, jwtTokenUtil),UsernamePasswordAuthenticationFilter.class);
}
/* To allow Pre-flight [OPTIONS] request from browser */
@Override
public void configure(WebSecurity web)
{
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
@Bean
public BCryptPasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
};
}
正如您在前面的代碼中看到的,我有以下兩個匹配器串列:
private static final String[] USER_MATCHER = { "/api/user/email/**"};
private static final String[] ADMIN_MATCHER = { "/api/users/email/**"};
目前,兩者都包含相同的 API 路徑:/api/users/email/**。這是因為我最初的想法是這個 API 應該可供簡單用戶和管理員用戶使用。
然后在代碼中,您可以根據生成的令牌中包含的權限找到以下匹配器定義:
.antMatchers(USER_MATCHER).hasAnyAuthority("CLIENT")
.antMatchers(ADMIN_MATCHER).hasAnyAuthority("ADMIN")
(USER_MATCHER與CLIENT權限有關,目前是可以執行的最簡單的操作型別...請不要過多關注權限名稱...這些主要是一些示例然后我將更好地定義我的權限串列)。
所以這樣做我希望這個/api/users/email/ API 必須為具有ADMIN權限的用戶以及具有CLIENT權限的用戶啟用。
不過好像不是真的,做個例子。我為具有ADMIN權限的用戶生成一個令牌,如下所示:
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ4eHhAZ21haWwuY29tIiwibmFtZSI6IlJlbmF0byBudWxsIEdpYWxsaSIsInVzZXJfcHJvZmlsZXMiOlsiQURNSU4iXSwiZXhwIjoxNjQwMjg2NTY5LCJpYXQiOjE2NDAyMDAxNjksImF1dGhvcml0aWVzIjpbIkFETUlOIl19.WQGYKbo_ihrV2Nu1RlxrCweBpgU-Y-dNh9L6R9vrj3vhTyvbPlsyzWNPe8ljtP6WZ8_Vvv8FUDJIa6y5BLS1SA
使用
好的,現在我為我的系統中只有CLIENT權限的另一個用戶生成了一個全新的 JWT 令牌。它生成這樣的東西:
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJ5eXlAZ21haWwuY29tIiwibmFtZSI6Ik1hcmlvIG51bGwgUm9zc2kiLCJ1c2VyX3Byb2ZpbGVzIjpbIkNMSUVOVCJdLCJleHAiOjE2NDAyODY5MzEsImlhdCI6MTY0MDIwMDUzMSwiYXV0aG9yaXRpZXMiOlsiQ0xJRU5UIl19.MYM6J3bGSK2PJvxPpi01BHjbcyOiONegYlbZ--lfEtg3p6Hw91acyKYC7KADC2KcJgcXnICJGmLTkPcrVIpfEw
像往常一樣,使用
如您所見,使用此令牌似乎禁止 API 訪問。
為什么如果在我的配置中我指定了定義到USER_MATCHER串列中的 API (所以以前的目標 API)也應該可以被具有包含CLIENT權限的令牌的用戶訪問?
怎么了?或者我在權限定義邏輯中缺少什么?
uj5u.com熱心網友回復:
聽起來您希望/api/users/email/CLIENT 和 ADMIN 都可以訪問端點
代替 .antMatchers(ADMIN_MATCHER).hasAnyAuthority("ADMIN")
嘗試 .antMatchers(ADMIN_MATCHER).hasAnyAuthority("ADMIN", "CLIENT)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/391915.html
