How to run RunAs using method security using Spring MVC 3.2 and Spring Security 3.1

I have a web application with Spring MVC 3.2 and Spring Security 3.1

I use basic role security and implemented UserDetailsService and UserDetails to provide GrantedAuthority.

I have enabled global method protection using jsr250 annotations

Everything that works here works as expected when subscribing to access to a custom method limited to declared roles.

I have one more requirement for running certain methods, called during application initialization, as a special user with a "system role" ideally along JavaEE RunAs strings. I am not sure how to do this in Spring Security.

Should I try to create a PreAuthenticatedAuthenticationToken with some composed values ​​and a "system role" authority.
Then I could do something like SecurityContextHolder.getContext().setAuthentication(token); upon application initialization.

Alternatively, I should try to use RunAsManager. This is similar to what I need, but I did not find simple examples of how I could use it.

I'm new to Spring Security, and I'm not sure how best to proceed.

+4
source share
3 answers

When my application starts

  • I am running a post build method in my spring bean to create a special user in memory with a system role.
  • This user object implements the interface.
      org.springframework.security.core.userdetails.UserDetails 
    .
  • Then I use the user to create a security token
      org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken 
  • Then, in the security context, a token is placed.

     @Service @Transactional(readOnly = true) public class ApplicationConfiguration{ @Inject MyService myService; @PostConstruct @Transactional(readOnly = false) public void init(){ // ######## Application Starting #######" // Create a user that meets the contract of the Spring UserDetails interface UserAccountImpl sysAcc = new UserAccountImpl("system", "system", "system"); UserRole role = new UserRole(Role.SYSTEM_ROLE); role.addUserPermission(Permission.SYSTEM); sysAcc.addUserRole(role); UserDetailsAdapter userDetails = new UserDetailsAdapter(sysAcc); // Create a token and set the security context PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken( userDetails, userDetails.getPassword(), userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(token); // Now call service method with roles allowed myService.initialiseSystem(); } } 

    ....

     public interface MyService { @RolesAllowed(SYSTEM) public void initialiseSystem(); } 
+4
source

Do you really need to attach the role to the specified application initialization? Why not just extract the code that needs to be run during initialization, for example:

 public interface Service { @Secured("hasRole('USER')") void service(); } public class DefaultService implements Service { @Override public void service() { doService(); } public void doService() { // Implementation here } } ... public class AppInitializer { @Autowired private DefaultService service; public void init() { service.doService(); } } 
+3
source

I believe that in this case, a good solution for you would be to use Spring Security OAuth, because you can more integrate custom rules for access through tokens.

http://projects.spring.io/spring-security-oauth/

+1
source

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


All Articles