Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorization in spring-security based on path variables

My use case is to authenticate & then authorize users based on @PathVariable parameters. I need to execute some custom code to authorize the principal. I'm not sure of the approach to take here -

  1. I have implemented a custom AbstractAuthenticationProcessingFilter & AuthenticationProvider for authentication, which ends up granting roles to the principal. I can inspect the pathvariables in the servlet request (using HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE), and add additional authorities to the Authentication token. Then I can use the built-in hasRole, hasPermission expressions to implement access control.

  2. I can extend WebSecurityExpressionRoot and implement a custom AbstractSecurityExpressionHandler and define my own expressions to be used in the intercept-url access-control expressions. I'm not sure how I can access the @PathVariables when defining custom methods in my WebSecurityExpressionRoot implementation.

Which approach is preferable, or is there another way to do this cleanly?

like image 637
Oceanic Avatar asked Oct 14 '15 02:10

Oceanic


People also ask

Which authorization levels are supported by Spring Security?

1. Overview. Simply put, Spring Security supports authorization semantics at the method level. Typically, we could secure our service layer by, for example, restricting which roles are able to execute a particular method — and test it using dedicated method-level security test support.

How does Spring Security authentication work internally?

The Spring Security Architecture There are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication. Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object.


1 Answers

I do have a solution. In a configuration class

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter

I could have method

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
            .antMatchers("/student/{id}/**")
            .access("@guard.checkUserId(authentication,#id)");
}

while @guard in SpEL links to

@Component
public class Guard {
    @Autowired
    private UserRepository repo;

    public boolean checkUserId(Authentication authentication, int id) {
        String name = authentication.getName();
        System.out.println(name+" at "+id);
        User result = repo.findByUsername(name);
        return result != null && result.getPid() == id;
    }
}

In practice, the #id in SpEL can get the value extracted from {id} in the previous line. You can do whatever you want in checkUserId, and the return value decides whether the access to the path would be allowed.

like image 132
HYisen Avatar answered Oct 03 '22 04:10

HYisen