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 -
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.
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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With