[SpringSecurity] Login based on MySQL user role

1. Create a class that inherits WebSecurityConfigurerAdapter

@EnableWebSecuritypublic class MySecurityConfig extends WebSecurityConfigurerAdapter {      @Autowired    private MyUserService userService;     @Override    protected void configure(AuthenticationManagerBuilder auth) throws Exception {         // 1. 基于数据库登录,自定义userDetailsService        auth.                userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());      }     @Override    protected void configure(HttpSecurity http) throws Exception {        http.authorizeRequests()                .antMatchers("/").permitAll()                .antMatchers("/client").hasRole("client")                .antMatchers("/store").hasRole("store")                .antMatchers("/admin").hasRole("admin");        http.formLogin();    }}

2. Create a class to implement UserDetailsService

@[email protected] class MyUserService implements UserDetailsService {     @Autowired    private UserMapper userMapper;     @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        // 根据用户名查询用户信息        User user = userMapper.queryUserByUsername(username);        return user;    }    }

3. View the mybatis code of the corresponding queryUserByUsername (username)

<select id="queryUserByUsername" resultType="com.lidantao.springsecurity.bean.User">        select *        from user        where username = #{username}    </select>

4. Database design (this design does not do rdbc model design, it is only used for simple demo demonstration, but also to distinguish the authority control hasRole and hasAuthority, which will be mentioned below)

5. Create a class User to implement UserDetails (the entity class returned by the mybatis query above)

@[email protected]@NoArgsConstructorpublic class User implements UserDetails {      @Autowired    private UserMapper userMapper;     private String id;    private String username;    private String password;    private String roles;     public String getPassword() {        return new BCryptPasswordEncoder().encode(password);    }     @Override    public Collection<? extends GrantedAuthority> getAuthorities() {        List<GrantedAuthority> auth = new LinkedList<>();        for (String role : roles.split(",")){            auth.add(new SimpleGrantedAuthority(role));        }        System.out.println(roles);        return auth;    }     // 账号是否过期    @Override    public boolean isAccountNonExpired() {        return true;    }     // 账号是否被锁    @Override    public boolean isAccountNonLocked() {        return true;    }     // 认证是否过期    @Override    public boolean isCredentialsNonExpired() {        return true;    }     // 用户信息是否开启    @Override    public boolean isEnabled() {        return true;    }}

6. Write the corresponding controller code and test the interface permissions

@Controllerpublic class UserController {      @RequestMapping({"/", "/index"})    public String index(){        return "index";    }     @RequestMapping("/client")    public String client(){        return "client";    }     @RequestMapping("/store")    public String store(){        return "store";    }     @RequestMapping("/admin")    public String admin(){        return "admin";    } }

(The front-end code is ignored)

7. Permission test

1. The homepage is accessed without permission, you can see from the above 1 permission control, the permission is: permitAll

2. Click on the customer and you will be redirected to the login page of springsecurity. This implementation is due to the implementation in 1 (http.formLogin)

The authorization is successful, because the role permissions are set in 1, the client user can access the client, try to click on the admin page below

Forbidden appears, due to insufficient permissions, because the client account in the database only has client and store role permissions set, and does not have admin permissions.

The test is complete.


8. Why should the roles column in the database be prefixed with ROLE_ instead of client directly, but ROLE_client, etc.?

At the beginning, I did not set the hasRole in 1, but set the hasAuthority, and found that the permissions can be accessed without ROLE_, but if the ROLE_ prefix is ​​not added in the database, there will be forbidden, no more nonsense , To test and analyze the source code.

Remove the prefix ROLE_ for all database roles, the permissions in 1 are still the hasRole unchanged, and the test begins

Click on the customer interface

Log in to the client account


It turned out to be 403. Is it amazing? Let’s analyze the difference between hasRole and hasAuthority.

Here, click me! ! !