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

Spring Secutirty hasRole始终返回403

张嘉熙
2023-03-14

我试图根据角色限制对endpoint的访问。我在stackoverflow上搜索了一个解决方案,尝试了一些,但没有成功地解决我的问题。我尝试在全局配置(WebSecurityConfig)和预授权注释中进行限制,调用时都返回403。我的测试用户拥有SYS_ADMIN角色,我已经验证了这个流,它实际上拥有这个角色。以下是我的消息来源。

全球网络安全配置

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

    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;

    @Autowired
    private UserDetailsService jwtUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    @Bean
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.headers().frameOptions().disable();

        httpSecurity.cors().and()
                .csrf().disable()
                .authorizeRequests()
                    .antMatchers("/spring-security-rest/**").permitAll().and()
                .authorizeRequests()
                    .antMatchers(HttpMethod.POST, "/api/authentication/**").permitAll()
                    .antMatchers(HttpMethod.POST, "/api/persons/**").hasRole("SYS_ADMIN")
                    .antMatchers(HttpMethod.GET, "/api/roles/**").permitAll()
                    .anyRequest().authenticated().and()
                .headers().frameOptions().sameOrigin().and()
                .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers(HttpMethod.OPTIONS, "/**");
        web.ignoring().mvcMatchers("/swagger-ui.html/**", "/configuration/**", "/swagger-resources/**", "/v2/api-docs",
                "/webjars/**");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

人员控制员

package br.com.aquamain.backend.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import br.com.aquamain.backend.exception.InvalidPersonException;
import br.com.aquamain.backend.model.CustomPage;
import br.com.aquamain.backend.model.Person;
import br.com.aquamain.backend.service.PersonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/api/persons")
@Api(tags = "Persons")
public class PersonController {

    @Autowired
    private PersonService personService;
    
    ...

    @PostMapping(path = "new", consumes = "application/json")
    @ApiOperation(value = "Create a new person.")
    public ResponseEntity<?> save(@RequestBody Person person) {
        try {
            CustomPage<Person> persons = this.personService.save(person);
            return new ResponseEntity<CustomPage<Person>>(persons, HttpStatus.CREATED);         
        } catch (InvalidPersonException error) {
            return new ResponseEntity<String>(error.getMessage(), HttpStatus.BAD_REQUEST);
        }
    }
    
    ...
}

榜样

package br.com.aquamain.backend.model;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@Entity
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
@Table(name = "AQUARIUM_MAINTANCE_MONITOR_ROLE")
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID_ROLE", nullable = false, precision = 9, scale = 0)
    private Integer id;
    
    @JsonIgnoreProperties(value = {"roles"})
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
    @JsonInclude(Include.NON_NULL)
    private List<User> users;
    
    @Column(name = "CODE_ROLE", nullable = true, length = 255)
    private String code;
    
    @Column(name = "DESCRIPTION_ROLE", nullable = true, length = 255)
    private String description;
    
    @Column(name = "NAME_ROLE", nullable = true, length = 255)
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }   
}

共有1个答案

袁枫涟
2023-03-14

控件上的角色权限是正确的。

@Secured( {"ROLE_myAuthority"} )

事实上,你得到了适当的批准。

new SimpleGrantedAuthority("ROLE_myAuthority");

UsernamePasswordAuthenticationToken对象确实授予权限。

过滤器已正确注入

Authentication auth = new UsernamePasswordAuthenticationToken(username, authentication.getCredentials(), authorities); 

Collection<? extends GrantedAuthority> auths = auth.getAuthorities();`

Iterator authsIterator = auths.iterator();

while (authsIterator.hasNext()) {
     SimpleGrantedAuthority sga =  (SimpleGrantedAuthority) authsIterator.next();
        sga.getAuthority();
    // ... 
}
 类似资料:
  • 我的安全配置似乎不正确。无论我在使用hasRole时做什么,我的endpoint总是返回403。 此外,除非我在这两个和。很明显,我遗漏了一些东西。 基本上,我希望所有内容都需要身份验证,但只有当用户是某些组的成员时(现在只需要admin),少数endpoint才可以访问。 我的安全配置如下。旁边的一切都有效。 我的AuthenticationConfiguration如下 我的Authoriza

  • 问题内容: 我以前使用过媒体播放器,但从未遇到过此问题。每当我尝试使用MediaPlayer.create()时,该方法都会使我为null,并且无法播放声音。有什么我想念的吗? 我的sound.mp3在我的原始文件夹中,通过将声音拖到eclipse中的文件夹中,我将其放置在其中。请帮忙,因为我以前玩过声音,所以这真的困扰我:( 问题答案: 如果create() API由于某种原因失败,则返回nul

  • 问题内容: 尽管是有效的类,但以下代码会打印。 文档说方法返回 由 aClassName 命名的类对象,或者如果当前没有加载该名称的类。如果 aClassName 为,则返回。 我也试图获得当前的viewcontroller已加载但仍然得到 可能是什么问题? 更新: 即使尝试这样做,我仍然可以 问题答案: 该函数 确实 适用于(纯和Objective-C派生的)swift类,但是仅当您使用全限定名

  • 问题内容: 我觉得有点愚蠢,但它不起作用: 我有如果给定的用户是unicode。如果字符串中包含或,我想打印成功,但是我总是得到的结果。 问题答案: 隐式锚定到字符串的开头。如果要在字符串中搜索可以在字符串中任何位置的子字符串,则需要使用: 输出: 另外,Python Regexes不需要在开头和结尾都有一个。 最后,我添加到该行的末尾,因为我认为这就是您想要的。否则,您会得到类似的信息,但并不太

  • 我正在尝试使用NSKeyDarchiver在应用程序关闭和运行周期之间存储数据。我试图存储的根对象是一个NSMutableArray,但在这个对象中有基础对象和自定义对象的集合(所有这些都符合NSCoding)。 文件保存代码如下 该文件保存fine并且不会抛出异常。再次启动应用程序时,使用以下代码恢复该文件。 在这一点上,sessionData总是为零,而pData是几千字节长的,因此我知道问题

  • 我有以下异常处理程序: 此代码应该包装异常并返回具有正确状态代码的ResponseEntity。