SpringBoot + SpringSecurity control authorization

Introduction to Licensing

Ordinary people think that when different roles log into the same system, depending on the role permissions, the different menus they see are control authorization. In fact, it is not. Whether the menu is displayed or not is only a design of the front-end interaction, and the access to the interface of the place that really needs authorization.

Ordinary systems usually have two ends, one is a business system for users (such as the buyer end of a shopping mall), and the other is a management end for company operators (which can count sales, users, and other information).
The permissions on the business side are usually relatively simple, and can be divided into whether to log in, or simple role distinction (such as ordinary users, VIP users). The management side is relatively complicated. The bigger the company, the more roles, and the more detailed the authority is divided.

Whether to log in authorization

Ordinary user login is mentioned in the basic use and personalized login configuration of SpringBoot + Spring Security before . Here are a few interfaces configured that can be accessed without login. I won't go into too much detail here.

Simple role distinction

AbstractChannelSecurityConfigIt is also configured in the configure method of the inherited class

@Configuration
public class BrowerSecurityConfig extends AbstractChannelSecurityConfig {
    http.authorizeRequests()        // 定义哪些URL需要被保护、哪些不需要被保护
        .antMatchers("/user/regist", "/session/invalid")
        .permitAll()                // 设置所有人都可以访问的接口
        .antMatchers("/user").hasRole("ADMIN")  // user接口只有ADMIN角色的可以访问
        .anyRequest()               // 其他任何请求,登录后可以访问
        .authenticated()
        .and()
}

Here, the role permissions are mainly controlled by using antMatchersand hasRolecollocation, so where are the role permissions assigned? is in the login management

@Component
public class MyUserDetailsService implements UserDetailsService {
@Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 演示用,随便给一个password
        String password = "123456";
        // 参数分别是:用户名,密码,用户权限
        User user = new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN));
        return user;
    }
}

AuthorityUtils.commaSeparatedStringToAuthorityListAccepts a string array, which contains the user's role. For example hasRole, if "ADMIN" is configured above, then "ROLE_ADMIN" needs to be passed in. ADMIN is case-sensitive.

When using restfulAPI, the interface address is the same, but the request method is different. At this time , the antMatchersrequest method can also be configured

// 此时POST方法会需要角色权限
antMatchers(HttpMethod.POST, "/user").hasRole("ADMIN")

Complex role permissions and permission expressions

The previous permission configuration was directly written in the configuration through code.
When faced with complex roles, roles and permissions are generally placed in the database. At this time, five database tables are generally involved, namely: user table, role table, permission table, user and role intermediate table, role and permission intermediate table.

Here we simulate an example of obtaining permissions from the database based on the current account

@Component("rbacPermission")
public class RbacPermission {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        Object principal = authentication.getPrincipal();
        boolean hasPermission = false;
        if(principal instanceof UserDetails) {
            String username = ((UserDetails) principal).getUsername();
            // 读取用户所拥有的权限url,这里应该从数据库获取
            Set<String> urls = new HashSet<>();

            for (String url : urls) {
                // 判断当前url是否有权限
                if(antPathMatcher.match(url, request.getRequestURI())) {
                    hasPermission = true;
                    break;
                }
            }
        }
        return hasPermission;
    }
}

The next step is to configure

http.authorizeRequests()
     .anyRequest()
     .access("@rbacPermission.hasPermission(request, authentication)");

accessis the permission expression

It should be noted that anyRequest() needs to be placed at the end

code download

Spring-Security

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325875768&siteId=291194637