Changing the security context for calling a method using spring-security

I am currently using spring security and @PreAuthorize annotations to protect method calls. Now I want to change the authentication token for the method call, for example, run as a replacement for spring./p> security authentication

Can I configure a base replacement for each method? In the annotation, the expression is SpEL .... If not, is it possible in runAsManager to find out which method is being called? How do I configure security configuration attributes for a protected object?

+6
source share
2 answers

I solved this by implementing my own RunAsManager , which checks the user annotation for the called method and returns the corresponding token.

works great.

+1
source

I published a detailed article on Run-As implementation in combination with @PreAuthorize .

1) Deploy your own RunAsManager , which creates Authentication for use at run time based on any user logic. The following example uses a custom annotation that provides an additional role:

 public class AnnotationDrivenRunAsManager extends RunAsManagerImpl { @Override public Authentication buildRunAs(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) { if(!(object instanceof ReflectiveMethodInvocation) || ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class) == null) { return super.buildRunAs(authentication, object, attributes); } String roleName = ((ReflectiveMethodInvocation)object).getMethod().getAnnotation(RunAsRole.class).value(); if (roleName == null || roleName.isEmpty()) { return null; } GrantedAuthority runAsAuthority = new SimpleGrantedAuthority(roleName); List<GrantedAuthority> newAuthorities = new ArrayList<GrantedAuthority>(); // Add existing authorities newAuthorities.addAll(authentication.getAuthorities()); // Add the new run-as authority newAuthorities.add(runAsAuthority); return new RunAsUserToken(getKey(), authentication.getPrincipal(), authentication.getCredentials(), newAuthorities, authentication.getClass()); } } 

This implementation will look for the @RunAsRole user-defined annotation for the protected method (for example, @RunAsRole("ROLE_AUDITOR") ) and, if found, will add this authority ( ROLE_AUDITOR in this case) to the list of granted permissions. RunAsRole itself is just a simple custom annotation.

 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface RunAsRole { String value(); } 

2) To issue a manager launch:

 <bean id="runAsManager" class="org.springframework.security.access.intercept.RunAsManagerImpl"> <property name="key" value="my_run_as_key"/> </bean> 

3) Register it:

 <global-method-security pre-post-annotations="enabled" run-as-manager-ref="runAsManager"> <expression-handler ref="expressionHandler"/> </global-method-security> 

4) An example of use in the controller:

 @Controller public class TransactionLogController { @PreAuthorize("hasRole('ROLE_REGISTERED_USER')") //Authority needed to access the method @RunAsRole("ROLE_AUDITOR") //Authority added by RunAsManager @RequestMapping(value = "/transactions", method = RequestMethod.GET) //Spring MVC configuration. Not related to security @ResponseBody //Spring MVC configuration. Not related to security public List<Transaction> getTransactionLog(...) { ... //Invoke something in the backend requiring ROLE_AUDITOR { ... //User does not have ROLE_AUDITOR here } 

EDIT: The key value in RunAsManagerImpl can be whatever you want. Here is an excerpt from Spring docs on its use:

So that the malicious code does not create RunAsUserToken and is present for guaranteed acceptance of RunAsImplAuthenticationProvider , the key hash is stored in all generated tokens. RunAsManagerImpl and RunAsImplAuthenticationProvider created in a bean context with the same key:

 <bean id="runAsManager" class="org.springframework.security.access.intercept.RunAsManagerImpl"> 

 <bean id="runAsAuthenticationProvider" class="org.springframework.security.access.intercept.RunAsImplAuthenticationProvider"> 

Using the same key, each RunAsUserToken can be verified; it was created approved by RunAsManagerImpl . RunAsUserToken unchanged after creation for security reasons.

+6
source

Source: https://habr.com/ru/post/921386/


All Articles