无法实现对 Spring-Boot API 的基于角色的访问

Unable to implement Role based access to Spring-Boot API

我是 Spring-Boot.I 的新手,想创建一个 API,它将具有基于角色的访问权限和基于 JWT 令牌的身份验证。但是,无法实现。

我没有使用 JPA 和 Hibernate 来获取和映射数据。相反,我使用 Ibatis.I 尝试过 @PreAuthorizeantMatchers & hasRole,但失败了。通过从 JWT 令牌获取用户 ID,我正在获取详细信息和角色并将它们设置为 SecurityContextHolder.getContext().setAuthentication,但仍然无法正常工作。

安全配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .csrf().disable()

   .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
          .and()
          .addFilter(new JwtAuthorizationFilter(authenticationManager()))
          .authorizeRequests()
          .anyRequest().authenticated()
          .antMatchers("api/management/reports").hasRole("Supervisor");
    }

控制器

@RestController
@RequestMapping("api")
@CrossOrigin
public class MyController {

    @PreAuthorize("hasRole('Supervisor')")
    @GetMapping("username")
    public String reports(){
        SecurityContext securityContext = SecurityContextHolder.getContext();
        return securityContext.getAuthentication().getName();
    }
}

授权过滤器

public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

@Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

String header = request.getHeader(JwtProperties.HEADER_STRING);
if (header == null || !header.startsWith(JwtProperties.TOKEN_PREFIX)) {
            chain.doFilter(request, response);
            return;
        }

        Authentication authentication = getUsernamePasswordAuthentication(request,header);
        SecurityContextHolder.getContext().setAuthentication(authentication);


        chain.doFilter(request, response);
}
private Authentication getUsernamePasswordAuthentication(HttpServletRequest request, String header) {
        try {
String token = header.replace(JwtProperties.TOKEN_PREFIX,"");
String userName = JWT.require(HMAC512(JwtProperties.SECRET.getBytes()))
                        .build()
                        .verify(token)
                        .getSubject();
List<User> searchedUserList = getUserDetailsDAO().getUserDetails(userName);


    if (null !=searchedUserList && searchedUserList.size()>0) {

        User searchedUser = new User();
        searchedUser = searchedUserList.get(0);
        List<RoleAccess> roleAccessList = new ArrayList<RoleAccess>();
    XrefUsrRole oXrefUsrRole = new XrefUsrRole();
    oXrefUsrRole.setUserName(searchedUser.getUsername());
    roleAccessList = getRoleAccessDAO().getAccessDetails(oXrefUsrRole);
    List<GrantedAuthority> authorities = uildUserAuthority(roleAccessList);

    org.springframework.security.core.userdetails.User newUser = buildUserForAuthentication(searchedUser, authorities);

UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(newUser, null,authorities);
                    return auth;
                }
                return null;
            }
            return null;
        } catch (IOException e) {
            return null;
        }

private org.springframework.security.core.userdetails.User buildUserForAuthentication(User searchedUser, List<GrantedAuthority> authorities) {
        return new org.springframework.security.core.userdetails.User(searchedUser.getUsername(), searchedUser.getPassword(), true, true, true, true, authorities);
    }

    private List<GrantedAuthority> buildUserAuthority(List<RoleAccess> roleAccessList) {
        Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

        // Build user's authorities
        for (RoleAccess userRole : roleAccessList) {
            setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
        }

        List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

        return Result;
    }

在这种情况下,api/username 应该无法访问,除非用户具有 主管 角色。

您有 ROLE_"+userRole.getModifiedBy()) 这意味着您正在授予 ROLE_NAME 角色在 PreAuthorize 中,您有导致问题的主管。您可以将角色存储为 ROLE_SUPERVISOR 在数据库中,然后按以下方式使用它

    // Build user's authorities
    for (RoleAccess userRole : roleAccessList) {
        setAuths.add(new SimpleGrantedAuthority("ROLE_"+userRole.getModifiedBy()));
    }

使用

@PreAuthorize("hasRole('ROLE_SUPERVISOR')")
.antMatchers("api/management/reports").hasRole("SUPERVISOR");