spring - 您可以在 @PreAuthorize 中使用 SpEL 引用实例属性吗?

标签 spring spring-security spring-el

有没有办法在类中使用局部变量(下面的authorizedRoles),该变量设置了所有角色以授予对hasAnyRole值的端点的访问权限?例如,我想要一个在配置中定义的角色列表,并在 @PreAuthorize 中填充 hasAnyRole,如下所示:

@Controller("myController")
public class MyController {
private String authorizedRoles;

@Autowired
public MyController(ObjectMapper objectMapper, @Value("#{'${security.authorized-roles}'.split(',')}") String authorizedRoles) {
    this.objectMapper = objectMapper;
    this.request = request;
    this.authorizedRoles = authorizedRoles;
}

@RequestMapping(value = "/id", produces = { "application/json" }, consumes = { "application/json" }, method = RequestMethod.POST)
@PreAuthorize("hasAnyRole('#myController.authorizedRoles')")
public ResponseEntity<IdResponse> idPost(@RequestBody IdRequest body) {
  ...
}

最佳答案

您无法使用 SpEL 那样访问私有(private)字段;您需要添加public String getAuthorizedRoles(),当您引用authorizedRoles属性时,SpEL将调用它。 SpEL 了解 JavaBean 约定。

编辑

hasAnyRole() 采用 String[]

@SpringBootApplication
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class So59419703Application extends GlobalAuthenticationConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(So59419703Application.class, args);
    }

    @Autowired
    private Foo foo;

    @Bean
    public ApplicationRunner runner() {
        return args -> {
            SecurityContext ctx = SecurityContextHolder.createEmptyContext();
            ctx.setAuthentication(new UsernamePasswordAuthenticationToken("foo", "bar"));
            SecurityContextHolder.setContext(ctx);
            System.out.println(foo.bar());
        };
    }

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("foo").password("bar").roles("baz");
    }

    public interface Foo {

        String bar();

        String[] getRoles();

    }

    @Component("foo")
    public static class FooImpl implements Foo {

        private final String[] roles = StringUtils.commaDelimitedListToStringArray("admin,user,baz");

        @Override
        @PreAuthorize("hasAnyRole(@foo.roles)")
        public String bar() {
            return "authOk";
        }

        @Override
        public String[] getRoles() {
            return this.roles;
        }

    }

}
authOk

关于spring - 您可以在 @PreAuthorize 中使用 SpEL 引用实例属性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59419703/

相关文章:

spring - Keycloak 和 Spring SAML : SigAlg was null

java - Spring 启动-com.mysql.jdbc.spring启动异常.jdbc4.MySQLSyntaxErrorException : Unknown column 'customer0_.email' in 'field list'

java - 使用 Spring boot 和 Jackson 的日期时区

java - 无法保护 Spring 引导管理执行器端点

java - ReactiveSecurityContextHolder.getContext() 为空但@AuthenticationPrincipal 有效

java - SpEL 表达式中转义冒号 ":"

java - 配置 Spring 以设置系统属性 'before' 初始化一个 bean

grails - 查找当前登录用户的用户角色

java - Spring Integration FtpOutboundGateway setLocalDirectory 与系统属性和#remoteDirectory

java - 为什么 SpEL 在 Spring Boot 和 Spring Cloud Stream @SendTo 中不起作用