我正在构建一个springboot应用程序,目前正在尝试实现基于权限的授权。在我的securityConfig文件中,基于角色的授权是有效的,但是基于权限的授权失败了。如下面的SecurityConfig文件所示,在antMatchers的hasAnyRole函数中传递角色是有效的,但是传递权限给hasAnyAuthority是无效的,也就是说,它没有授权。
这是我的SecurityConfig文件
@Override
protected void configure(HttpSecurity http) throws Exception {
/*
* Setting custom login endpoint
* */
CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter(authenticationManagerBean());
customAuthenticationFilter.setFilterProcessesUrl("/api/login");
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.authorizeRequests()
.antMatchers("/api/login/**", "/api/token/refresh/**").permitAll()
.antMatchers("/api/users/save/**").permitAll()
.antMatchers(GET, "/api/users/**").hasAnyAuthority(CAN_ADD_MEMBER_TO_CHAMA.getPermission())
.antMatchers(GET, "/api/users/**").hasAnyRole(PLATFORM_SUPER_ADMIN.name())
.anyRequest()
.authenticated()
.and();
http.addFilter(customAuthenticationFilter);
http.addFilterBefore(new CustomAuthorizationFilter(), UsernamePasswordAuthenticationFilter.class);
}
职务
public enum ApplicationUserRole {
PLATFORM_SUPER_ADMIN(
Sets.newHashSet(
CAN_CREATE_CHAMA, CAN_DELETE_CHAMA,
CAN_UPDATE_CHAMA, CAN_INVITE_NEW_USER)),
PLATFORM_USER(Sets.newHashSet(CAN_CREATE_CHAMA)),
CHAMA_MEMBER(Sets.newHashSet(CAN_MAKE_CONTRIBUTION, CAN_INVITE_NEW_USER));
private final Set<ApplicationUserPermission> permissions;
ApplicationUserRole(Set<ApplicationUserPermission> permissions) {
this.permissions = permissions;
}
public Set<ApplicationUserPermission> getPermissions() {
return permissions;
}
public Set<SimpleGrantedAuthority> getGrantedAuthorities() {
Set<SimpleGrantedAuthority> permissions = getPermissions().stream()
.map(permission -> new SimpleGrantedAuthority(permission.getPermission()))
.collect(Collectors.toSet());
permissions.add(new SimpleGrantedAuthority("ROLE_" + this.name()));
return permissions;
}
}
使用权限
package com.chama.chamaservice.config;
public enum ApplicationUserPermission {
CAN_CREATE_CHAMA("CAN_CREATE_CHAMA"),
CAN_DELETE_CHAMA("CAN_DELETE_CHAMA"),
CAN_UPDATE_CHAMA("CAN_UPDATE_CHAMA"),
private final String permission;
ApplicationUserPermission(String permission) {
this.permission = permission;
}
public String getPermission() {
return permission;
}
}
自定义授权筛选器
public class CustomAuthorizationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (request.getServletPath().equals("/api/login") || request.getServletPath().equals("/api/refresh/token")) {
filterChain.doFilter(request, response);
} else {
// Generate new access token from refresh token
String authorizationHeader = request.getHeader(AUTHORIZATION);
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
try {
String token = authorizationHeader.substring("Bearer ".length());
Algorithm algorithm = Algorithm.HMAC256("secret".getBytes());
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT decodedJWT = verifier.verify(token);
String phoneNumber = decodedJWT.getSubject();
String[] roles = decodedJWT.getClaim("roles").asArray(String.class);
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
stream(roles).forEach(role -> {
authorities.add(new SimpleGrantedAuthority("ROLE_" + role)); // Populate ROLES
});
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phoneNumber, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response);
} catch (Exception e) {
log.error("Error logging in: {}", e.getMessage());
response.setHeader("error", e.getMessage());
response.setStatus(FORBIDDEN.value());
Map<String, String> error = new HashMap<>();
error.put("message", e.getMessage());
response.setContentType(APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(response.getOutputStream(), error);
}
} else {
filterChain.doFilter(request, response);
}
}
}
}
1条答案
按热度按时间nkhmeac61#
在您的自定义过滤器中,您只将 “roles” JWT声明解析为
String
形式的角色,因此您的SecurityContext
对权限(权限)一无所知。请尝试使用
ApplicationUserRole
枚举.getGrantedAuthorities()
方法来代替此方法,例如:如果 “roles” 声明无法解析为
ApplicationUserRole
数组,则.valueOf()
方法将抛出IllegalArgumentException
,并且您的catch
块将把它转换为403 http状态响应。