Spring Security使用类中的变量值进行身份验证

时间:2017-12-18 10:10:03

标签: spring spring-boot spring-security spring-security-oauth2 spring-security-rest

我在我的应用程序中使用Spring Security。我正在根据角色(ADMIN,USER)对API进行身份验证。 有一个API端点,我想使用作为参数传递给它的变量的值来限制访问。

我有

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {

    httpSecurity.csrf().disable().exceptionHandling().authenticationEntryPoint(this.unauthorizedHandler).and()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
            .antMatchers("/api/**").authenticated()
            .anyRequest().permitAll();

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

我有一个电话

@PostMapping("/something")
public ResponseEntity<BotResponse> handleRequest(@Valid @RequestBody SomeClass someClass) {
        // if someClass.getSomeValue() is not present in the User permissions, then it should give an unauthorized response.
        return value(someClass);
}

Spring Security中的用户是:

public Class User {
    String userId;
    String userName;
    String authorities;
    List<String> someList;
    //Getters and setters for variables
}

使用的SomeClass是:

public Class SomeClass {
    String someValue;
    String userName;
    ...
    // Getters and Setters
}

如果用户的someList中是否存在someClass.getSomeValue的值,我如何不允许用户?

2 个答案:

答案 0 :(得分:0)

根据您的问题,一种方法是将UserDetails存储在Spring Security Authentication Context中,然后根据作为参数传递的值检查此上下文对象中的相关数据。我假设您已将所有必需值存储在安全上下文中。
此检查可以在端点代码本身中完成(如果您有少量此类API)。如果有多个API需要相同的逻辑,则必须实现仅过滤这些API的过滤器(配置可以用web.xml编写)或切入点(通过AOP)。

答案 1 :(得分:0)

也许你可以使用spring的全局方法安全性进行这种授权。

要使用方法级别授权,您需要将以下注释添加到安全配置类。

@EnableGlobalMethodSecurity(prePostEnabled = true)

然后使用Spring Expression Language将@PreAuthorize应用到您的终点。像...这样的东西。

@PostMapping("/something")
@PreAuthorize("@someService.checkUserAccess(principal, #someClass)")
public ResponseEntity<BotResponse> handleRequest(@Valid @RequestBody SomeClass someClass) {
        // if someClass.getSomeValue() is not present in the User permissions, then it should give an unauthorized response.
        return value(someClass);
}

@someService是一个Bean,您可以在Controller中自动装配并定义checkUserAccess()方法。像...这样的东西。

public boolean checkUserAccess(Pricipal principal, SomeClass someClass) {
      // here you can fetch your full user object from db or session (depending on your application architecture)
      // apply what ever logic you want to apply, return true if user has access and false if no.
}

注意/建议 - 如果您的应用程序设计允许,您可以将此checkUserAccess()方法添加到现有用户服务中,并在控制器中自动装配用户服务。