当前位置: 首页 > 知识库问答 >
问题:

Spring Security:具有角色的用户无法访问endpoint

亢建木
2023-03-14

我创建了这个简单的控制器:

@RestController
@RequestMapping("/orders")
public class OrderController {

    @GetMapping("/list")
    @PreAuthorize(value = "hasRole('VIEWER')")
    public List<String> list() {
        return new ArrayList<String>();
    }

}

如您所见,它受@PreAuthorize(value="hasRole('VIEWER')")的保护。

根据日志:

Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@99305100: Principal: username; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: VIEWER
Voter: org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter@4799314a, returned: -1
Voter: org.springframework.security.access.vote.RoleVoter@41e7ad2c, returned: 0
Voter: org.springframework.security.access.vote.AuthenticatedVoter@79a89d7d, returned: 0
Access is denied (user is not anonymous); delegating to AccessDeniedHandler

org.springframework.security.access.AccessDeniedException: Access is denied

如您所见,用户已通过身份验证,并具有角色查看器。然而,由于“访问被拒绝”,它无法到达endpoint。

上一个日志片段:

主体:用户名;凭据:[受保护];身份验证:真;详细信息:空;授予权限:查看者

我的JWTFilter看起来像:

package com.tsystems.covid.marketplace.backend.config.security;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;

public class JWTAuthorizationFilter extends OncePerRequestFilter {

    private static final Logger LOG = LoggerFactory.getLogger(JWTAuthorizationFilter.class);

    private TokenProperties tokenProperties;

    public JWTAuthorizationFilter(
        TokenProperties tokenProperties
    ) {
        this.tokenProperties = tokenProperties;
    }

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

        Claims claims = this.getAuthorizationToken(request)
            .map(this::validateToken)
            .orElse(null);

        if (null != claims) {
            this.setUpAuthentication(claims);
        }

        filterChain.doFilter(request, response);
    }

    /**
     * 
     * @param request
     * @return
     */
    private Optional<String> getAuthorizationToken(HttpServletRequest request) {
        return Optional
            .ofNullable(request.getHeader(SecurityConstants.AUTHORIZATION_HEADER))
            .filter(header -> header.startsWith(SecurityConstants.TOKEN_PREFIX))
            .map(header -> header.replace(SecurityConstants.TOKEN_PREFIX, ""));
    }

    /**
     * 
     * @param token
     * @return
     */
    private Claims validateToken(String token) {
        return Jwts.parser()
            .setSigningKey(this.tokenProperties.getSecret())
            .parseClaimsJws(token)
            .getBody();
    }

    /**
     * 
     * @param claims
     */
    private void setUpAuthentication(Claims claims) {
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(
            claims.getSubject(),
            null,
            this.parseAuthorities((List<String>)claims.get(SecurityConstants.JWT_AUTHORITIES_CLAIM))
        );

        SecurityContextHolder.getContext().setAuthentication(auth);
    }

    /**
     * 
     * @param authorities
     * @return
     */
    private List<GrantedAuthority> parseAuthorities(List<String> authorities) {
        return authorities
            .stream()
            .map(SimpleGrantedAuthority::new)
            .collect(Collectors.toList());
    }

}

有什么想法吗?

共有2个答案

爱乐邦
2023-03-14

如果您授予了权限:VIEWER,那么您需要使用hasAuthority。

@PreAuthorize(value = "hasAuthority('VIEWER')")

如果你想使用hasRole然后通过授予权限:ROLE_VIEWER然后你可以使用这个:

@PreAuthorize(value = "hasRole('VIEWER')")
娄德运
2023-03-14

我认为这是因为Spring的默认前缀试图使其

@RestController
@RequestMapping("/orders")
public class OrderController {

    @GetMapping("/list")
    @PreAuthorize(value = "hasRole('ROLE_VIEWER')")
    public List<String> list() {
        return new ArrayList<String>();
    }

}

因为默认情况下在角色之前添加ROLE_

 类似资料:
  • 问题内容: 我想为具有以下角色之一(ROLE1或ROLE2)的用户定义某些页面的访问权限 我正在尝试在我的spring security xml文件中进行如下配置: 我尝试了各种方法,例如: 等等 但似乎没有任何效果。 我一直在例外 要么 应该如何配置? 谢谢 问题答案: 问题是我配置了自定义 ,但没有通过其中一名选民。 通过添加到bean中来解决。

  • 我正在尝试使用Sonatype Nexus OSS 2.11.2-06通过Active Directory对用户进行身份验证。以下 https://books.sonatype.com/nexus-book/reference/ldap-sect-mapping-active-directory.html: 我已经设置了“LDAP配置”设置,以便“检查身份验证”成功,当我单击“检查用户映射”时,它

  • 我在一个有这种结构的拉威尔项目中工作 用户:id | first | u name |。。。 角色:id|name 分配的角色:id |用户id |角色id 我认为这是很明显的:p 用户模型 角色模型 我正在寻找一种方法来获取所有具有指定角色(在本例中为“教师”)的用户。我试过这个: 但这总是返回一个包含所有用户的数组。 有人知道为什么会这样吗?谢谢

  • 我有3个表:User、Role和具有Role\u id和User\u id的透视表RoleUser。 对于关系在我的模型我这样做: 榜样: 用户模型: 我为filter by one角色做了这项工作,效果很好: 但是现在我需要通过许多角色来过滤我的用户。 我将从我的前端发送一个数组,其中包含角色的id。 事实上,我可以得到如下角色 但我不知道如何才能获得具有此角色的用户。

  • 我的Spring Security性有问题,因为当我登录到这个站点时,我无法通过角色admin访问url。这是我的安全配置 我试图与hasRole, hasAuthure, hasAny权威,但不工作,只有工作许可所有,但我不想访问的东西url用户与角色用户 这是我的登录控制器 我在数据库中有两个用户,一个是角色管理员,第二个是角色用户,但这不起作用,有人能解释为什么吗? https://gith

  • 我想在laravel中创建一个RBAC系统,其中一个用户可以属于多个角色,每个角色可以有多个权限。中间件应在继续请求之前检查用户是否具有特定权限(在其任何角色内)。 我能够实施一个案例,其中 用户属于一个具有多个权限的角色 我需要实现具有多个权限的多个角色的用户。有什么指点吗?