Principle analysis and authority system design of spring security

Time:2019-12-11

Spring security and Apache Shiro are the two main open source security frameworks in the Java field, and they are also the main technology selection for permission system design. This paper mainly introduces the implementation principle of spring security, and designs a permission system based on RBAC based on spring security.

I. technology selection

Why spring security is used as the technology selection of permission system mainly considers the following aspects:

  1. Data authentication capability: Spring security supports data authentication, that is, fine-grained permission control.
  2. Spring ecological foundation: Spring security can be seamlessly integrated with spring ecology.
  3. Multiple certification capabilitiesSpring security supports multiple authentication methods, such as pre authentication which can be integrated with the third-party authentication system.
Spring Security Apache Shiro
Authentication Support multiple authentication methods (such as password, anonymityPre certification Simple login authentication
authentication Functional authenticationData authentication Function authentication
Multi-source adaptation Mem、JDBC、DAO、LDAP、
Openid, OAuth, etc
LDAP、JDBC、Kerberos、
Active directory, etc
encryption Support multiple encryption methods Simple encryption
Running environment Rely on Spring Independent operation
Openness Open source, spring ecological foundation Open Source
Complexity Complex and heavy Simple and flexible

II. Core structure

Authorization system generally consists of two core modules: authentication and authorization.

  • Authentication: the authentication module is responsible for verifying the validity of the user‘s identity, generating the authentication token, and saving it to the server session (such as TLS).
  • authentication: the authentication module is responsible for obtaining the user’s identity information from the server session and comparing the permissions with the accessed resources.

The official core architecture of spring security is as follows:
Principle analysis and authority system design of spring security

Core structure interpretation:

  • AuthenticationManager: responsible for authentication management, parsing user login information (encapsulated in authentication), reading user, role and authority information for authentication, and backfilling authentication results to authentication and saving in securitycontext.
  • AccessDecisionManager: responsible for authentication voting, summarizing the results of the voter, and implementing the strategy of one vote pass (default), multiple votes pass and one vote veto.
  • SecurityInterceptor: responsible for permission interception, including web URL interception and method call interception. Obtain the description information of the resource through configuattributes, and intercept the authentication with the help of accessdecisionmanager.
  • SecurityContext: security context, save authentication results. Three strategies are provided: global context, thread inheritance context and thread independent context (default).
  • Authentication: authentication information, saving the user’s identity, permission list, certificate, authentication pass mark and other information.
  • SecuredResource: resources under security control, such as web URL, user, role, custom domain object, etc.
  • ConfigAttributes: resource attribute configuration, which describes the information of security control resources and provides the input of interception logic for securityinterceptor.

III. design principle

By analyzing the source code, I sorted out the core domain model design of spring security as follows:
Principle analysis and authority system design of spring security

Interpretation of global abstract model:

  • To configure: authenticationconfiguration is responsible for the global configuration of authentication system, and globalmethodsecurityconfiguration is responsible for the global configuration of method call interception.
  • structure: authenticationconfiguration builds authentication manager AuthenticationManager through authenticationmanagerbuilder. Globalmethodsecurityconfiguration will automatically initialize abstractsecurityinterceptor to intercept method calls.
  • Web interception: httpsecurity configures the security of the web. A large number of genericfilterbean filters are built in to intercept URLs. The filter responsible for authentication will be authenticated through the AuthenticationManager, and the authentication result will be saved to the securitycontext.
  • Method Interception: Spring intercepts methods marked with @ preauthorize, @ prefilter, @ postauthorize, @ postfilter and other annotations through AOP technology (cglib / AspectJ), and calls AuthenticationManager through abstractsecurityinterceptor for authentication (if necessary).
  • Authentication: authentication manager authentication manager has built-in multiple authenticators authenticationproviders. As long as one of them passes the authentication, the authentication will succeed. Different authentication providers obtain the information they need (HTTP request, database query, remote service, etc.) for authentication, and the authentication results are all encapsulated in authentication. Authenticators (such as password authentication, pre authentication, etc.) that need to load user, role and permission information need to interface with userdetailsmanager to realize user crud function.
  • authentication: the authority interceptor abstractsecurityinterceptor loads the description information configattribute of the resource to be authenticated by reading different securitymetadatasources, and then passes the authentication information, resource description configattribute, and resource object itself to accessdecisionmanager for voting. Accessdecisionmanager has built-in multiple voter accessdecisionvoter. The voter will convert configattribute in authentication information to springel format. The expression processor securityexpressionhandler will execute expression based authentication logic, which will be forwarded to various operations of securityexpressionroot through reflection.
  • Customized: http security configuration can be customized through websecurity configureadapter httpsecurity and authentication manager generator authenticationmanagerbuilder; pre authentication filter can be customized through abstractpreauthenticated processingfilter; custom data source can be docked through userdetailsmanager and userdetails interface; permission information can be customized through grantedauthority; permission The evaluator can customize the access control logic of the domain model.

IV. application integration

After clearing the customization points of spring security, you can integrate spring security within the system.

Here, pre authentication is used to adapt to the third-party authentication system. Abstractpreauthenticatedprocessingfilter provides the extension point of pre authentication, and implements a custom authentication filter based on the abstract class.

public class MyPreAuthFilter extends AbstractPreAuthenticatedProcessingFilter {
    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        //Get user ID from third party system
        return userId;
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        return "";
    }
}

Spring security will load the initial information such as user role according to the user ID information returned by the pre authentication filter getpreauthenticatedprincipal. The user details manager interface is needed to provide the user information manager.

@Service
public class MyUserManager implements UserDetailsManager {
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //Load user information from database
        return user;
    }
    
    //Other management interfaces
}

Userdetails contains the permission information abstraction of the grantedauthority interface type, which can be used to customize roles and permissions. Spring security uses an interface to express roles and permissions. The difference between roles and permissions is that the ID of roles is prefixed with “role”.

public class MyRole implements GrantedAuthority {
    private final String role;

    @Override
    public String getAuthority() {
        return "ROLE_" + role;
    }
}

public class MyAuthority implements GrantedAuthority {
    private final String authority;

    @Override
    public String getAuthority() {
        return authority;
    }
}

Next, register the custom authentication filter and user manager. Here you need to implement the websecurityconfigureradapter for web security configuration.

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.PROXY)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsManager userDetailsManager;

    @Bean
    protected AuthenticationProvider createPreAuthProvider() {
        //Register user manager
        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsManager));
        return provider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //Register pre certified filter
        http.addFilter(new MyPreAuthFilter(authenticationManager()));
    }
}

In this way, the simplest spring security framework integration within the system has been completed. The following methods can be used for authentication on any service interface of the system.

public interface MyService {
    @PreAuthorize("hasAuthority('QUERY')")
    Object getById(String id);
    
    @PreAuthorize("hasRole('ADMIN')")
    void deleteById(String id);
}

Preauthorize annotation indicates authentication before calling. Spring uses dynamic proxy technology to generate authentication logic by default. The springel expression is configured in the annotation to customize the authentication mode. In the above code, hasauthority checks whether the user has query permission, and hasrole checks whether the user has the admin role.

AOP using dynamic proxy only allows permission interception at the interface level. If you want permission interception on any method, you need to use AspectJ for AOP. First, set the mode of the annotation enableglobalmethodsecurity to advicemode.aspectj, and then add the JVM startup parameter, so that you can use the annotation of spring security on any method.

-javaagent:/path/to/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar

The above permissions are only based on the user’s identity information (role / permission), which has limited flexibility and can not play the data authentication ability of spring security. To use data authentication, you need to implement a spring bean.

@Component
public class MyPermissionEvaluator implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        //User defined data authentication
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        //User defined data authentication
        return false;
    }
}

The permissionevaluator is automatically registered with the spring security framework and allows authentication within annotations in the following ways.

@PreAuthorize("hasPermission(#id, 'QUERY')")
Object func1(String id) {
}

@PreAuthorize("hasPermission(#id, 'TABLE', 'QUERY')")
Object func2(String id) {
}

The annotation of func1 indicates to verify whether the user has query permission on ID, and the code logic is routed to the first interface of mypermissionevaluator. The annotation of func2 indicates to verify whether the user has query permission on the ID of table type, and the code logic is routed to the second interface of mypermissionevaluator. Permissionevaluator provides the extension point of data authentication in permission system. Later, we will describe how to use the extension point to customize RBAC based permission system.

V. authority system

To build a RBAC (role based access control) based permission system, we need to clarify the meaning of the core concept classes of user, role, permission and resource and the relationship between them.

  • Resources: the objects that need to be controlled safely in the authority system are generally the data or functions in the system.
  • Jurisdiction: describes the operation abstraction on resources, which is generally an action.
  • To grant authorization: a combination of permissions and resources, indicating an operation on resources.
  • role: describes a set of authorizations representing a functional set of special concepts.
  • user: the main body of the permission system is generally the access user of the current system, and the user can have multiple roles.

The following is the core domain model of permissions based on RABC designed by us:
Principle analysis and authority system design of spring security

In general, resources that need permission control in the system cannot be customized by users. Because resources are coupled with a large number of business logic, we provide resources from resource factories to build business modules through configuration. Users, roles, permissions, and authorization records can be queried and updated through the corresponding manager.

In addition, resource abstraction allows the expression of inheritance and combination of resources, and then the expression of more complex resource models. The process of unified resource authentication is as follows:
Principle analysis and authority system design of spring security

  • When performing authentication, first of all, it depends on whether the resource is atomic or composite.
  • For atomic resources, first query whether there is authorization record, and then check whether the role pre authorization includes the current authorization. One of them is successful.
  • For atomic resources without authorization record and role pre authorization, try to replace authentication with parent resource (if any), otherwise authentication fails.
  • For combined resources, first expand the resources to get the list of sub resources.
  • Traverse the list of sub resources, and authenticate the sub resources in turn. After the result of sub resource authentication is summarized, the result of resource authentication is combined.

To sum up, based on the unified resource abstraction and resource allocation construction, the unified construction of resources can be realized, and then the unified authentication can be realized.

Vi. summary and review

Starting from the architecture and principle of spring security, this paper describes the design ideas and details of open source security framework for authentication and authentication modules. The method of integrating spring security in the system is provided, and the design and implementation of unified resource construction and unified authentication are discussed in combination with RBAC general permission system model. If you also need to design a new permission system, I hope this article can help you.