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

[[编辑]]JWT Spring Security:如何读取角色。hasRole()或。hasAuthority(),其中他们查看用户角色

云何平
2023-03-14

我试图使用HTTP配置中的角色向spring actuator服务添加授权,但它不起作用,响应为“禁止403”,这意味着用户未经授权<因此,我的问题是,具体在哪里。hasRole()在使用JWT令牌时查找已登录的用户角色

这是类中扩展WebSecurityConfigrerAdapter类的config方法

    protected void configure(HttpSecurity http) throws Exception {
    http.cors()
        .and()
        .csrf().disable()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .addFilterBefore(new JwtTokenVerifier(jwtConfig), UsernamePasswordAuthenticationFilter.class)
        .authorizeRequests()
        .antMatchers("/auth/**").permitAll()
        .antMatchers("/actuator/**").hasRole("ACTUATOR")
        .anyRequest()
        .authenticated()
        .and()
        .formLogin().disable();
    }   

这里我把JWT令牌中的角色

public String generateJwtToken(UserDetailsImpl userDetails) {
        Map<String, Object> claims = new HashMap<>();
        Set<String> Userroles = new HashSet<>();

        Role r1 = new Role();
        r1.setDescription("ROLE_ACTUATOR");
        r1.setId(1L);
        
        Set<Role> roles = new HashSet<>();
        roles.add(r1);
        
        for(Role role:roles){
            Userroles.add(role.getDescription());
        }
        claims.put("Roles",Userroles.toArray());
        claims.put("userId", userDetails.getId());
        
    return Jwts.builder()
            .setClaims(claims)
        .setSubject(userDetails.getUsername())
        
        .setIssuedAt(new Date())
        .setExpiration(java.sql.Date.valueOf(LocalDate.now().plusDays(getTokenExpirationAfterDays())))
        .signWith(Keys.hmacShaKeyFor(getSecretKey().getBytes())).compact();
    }  

那么什么是错的或缺失的呢?提前感谢
以下是JWT自定义筛选器的更新:

public class JwtTokenVerifier extends OncePerRequestFilter {

    private JwtConfig jwtConfig;

    public JwtTokenVerifier(JwtConfig jwtConfig) {
    super();
    this.jwtConfig = jwtConfig;
    }

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

    String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
    if (authorizationHeader == null || authorizationHeader.isEmpty() || !authorizationHeader.startsWith(jwtConfig.getTokenPrefix())) {
        String requestParam = request.getParameter("token");
        if (requestParam != null && !requestParam.isEmpty() && requestParam.startsWith(jwtConfig.getTokenPrefix())) {
        authorizationHeader = requestParam;
        } else {
        filterChain.doFilter(request, response);
        return;
        }
    }
    try {
        if (jwtConfig.validateJwtToken(authorizationHeader)) {
        String username = jwtConfig.getUserNameFromJwtToken(authorizationHeader);

        Authentication auth = new UsernamePasswordAuthenticationToken(username, new WebAuthenticationDetailsSource().buildDetails(request), null);
        SecurityContextHolder.getContext().setAuthentication(auth);
        }

    } catch (Exception e) {
        e.printStackTrace();
        response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
    }
    filterChain.doFilter(request, response);
    }

}

共有2个答案

於宾白
2023-03-14

感谢@SteveRiesenberg,正如聊天中所说,“如果自定义JWT筛选器没有处理角色,那么这就是问题所在。在执行身份验证时,必须填充角色(权限)。”
因此,由于角色不在筛选器中处理,因此它们不会通过安全链传递
过滤器的代码编辑如下:

UserDetailsImpl userDetails  = (UserDetailsImpl) userDetailsService.loadUserByUsername(username);
Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
                
Authentication auth = new UsernamePasswordAuthenticationToken(username, new WebAuthenticationDetailsSource().buildDetails(request), authorities); 

其中权限传递给UsernamePasswordAuthentiationTokenUserDetailsImpl是Spring提供的UserDetailsImpl类的实现

曹伟泽
2023-03-14

WebSecurityConfigrerAdapter扩展中,我看到了ACTUATOR,但在用户详细信息定义中,我看到了ROLE_ACTUATOR。这是不匹配吗?

 类似资料:
  • 如果消息作者尝试了,我如何使我的bot不接受消息作者的最高角色? 我尝试使用,但没有成功。 我的代码:

  • 编辑角色       点击编辑角色按钮,打开编辑角色面板,修改需要变更的内容。点击确定保存结果。

  • 我是LDAP的新手,我尝试过在OpenLDAP上实现RBAC。我创建了一些用户(inetOrganizationPerson)并将它们放在组中(groupOfNames)。接下来,我创建了一些角色(organizationalRole)并将它们与用户组关联(RoleIncuspant),而不是直接将它们与用户关联。 1)/usr/local/bin/ldapsearch-x-b'ou=groups

  • 我最近创建了一个非常基本的站点,用户可以在其中登录,然后访问一个他们可以编辑的表。我希望用户只能编辑自己的详细信息,而不能编辑其他人的详细信息,我不知道应该向代码中添加什么才能做到这一点。下面是编辑页面看起来像atm(我知道这样显示密码不是很安全,这只是一个例子) 更新:我不知道我应该添加到删除页面的值,所以它只删除登录用户的详细信息,而不删除任何人的。目前它没有删除任何细节。这是我的注册页面 这

  • 我想知道为用户分配的站点角色名称列表。所以我试着如下, 我只能看到用户的常规类型角色。不是网站类型。但在我的情况下,用户是网站管理员。那么如何使用api调用获取用户的站点角色名称呢?

  • 在roles/ansible-role-deploy-other-thing/tasks/main.yml中,以下内容被称为: 运行时,此会导致以下错误: 错误!在/users/myuser/playbooks/deploy-thing/roles:/users/myuser/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles:/u