我正在使用Spring Security和JWT令牌开发一个Spring引导程序来保护我的API,我有以下iusse。
我有一个API处理端点,如下所示:http://localhost:8019/api/admin/user/54/wallet
我有两种用户类型:
-
管理员用户:
有
管理
在JWT标记中定义的autority。
-
客户端用户:
有
客户
在JWT标记中定义的autority。
之前的API必须能被两种用户类型访问(我知道
/管理员/
URI中的部分不是最好的。。。它将在不久的将来进行重构)。
然后我让这门课扩展弹簧靴
Web安全配置适配器
类并实现我的安全配置:
@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[] CLIENT_MATCHER = {
"/api/users/email/*",
//"/api/admin/**",
"/api/admin/user/{userID}/wallet"
};
private static final String[] ADMIN_MATCHER = {
"/api/users/email/**",
"/api/admin/users",
"/api/admin/user/{userID}/wallet",
"/api/admin/**"
};
@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(CLIENT_MATCHER).hasAnyAuthority("CLIENT")
.antMatchers(ADMIN_MATCHER).hasAnyAuthority("ADMIN")
//.antMatchers(CLIENT_MATCHER).hasAnyAuthority("CLIENT")
.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, "/**");
web.ignoring().antMatchers("/swagger-ui/**",
"/webjars/**",
"/v2/**",
"/swagger-resources/**",
"/swagger-ui.html");
}
@Bean
public BCryptPasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
};
}
问题是,如果我尝试调用之前的API,正如前面的配置中定义的那样(http://localhost:8019/api/admin/user/54/wallet)与具有
客户
autority我正在获取此错误消息:
{
"timestamp": "2022-02-13T20:22:10.418+00:00",
"status": 403,
"error": "Forbidden",
"message": "Forbidden",
"path": "/api/admin/user/54/wallet"
}
反之,如果我试图调用前一个API,并传递一个拥有
阿姆丁
授权我获得预期的API输出。
这对我来说很奇怪,因为
客户匹配器
我定义了这个规则:
"/api/admin/user/{userID}/wallet"
最奇怪的是如果我从
管理员匹配器
:
"/api/admin/user/{userID}/wallet",
变成了这样:
private static final String[] ADMIN_MATCHER = {
"/api/users/email/**",
"/api/admin/users",
//"/api/admin/user/{userID}/wallet",
"/api/admin/**"
}
现在的行为完全相反:使用拥有
客户
授权我检索预期的输出,但现在使用拥有
管理
authoruty I获取此错误消息:
{
“时间戳”:“2022-02-13T20:27:47.793+00:00”,
“状态”:403,
“错误”:“禁止”,
“信息”:“禁止”,
“路径”:“/api/admin/user/54/wallet”
}
这对我来说很奇怪因为
管理员匹配器
继续这条规则:
"/api/admin/**"
这应该意味着:
访问所有API,其enptoint以“/API/admin/”开头,后跟任何其他内容
.
我的Spring配置有什么问题?我错过了什么?我如何修复它,使这个API可以使用JWT令牌访问
管理
或
客户
权威