The basics of Spring Security have been covered. Here is a small project to implement the three validation methods of Spring Security again

Spring Security Fundamentals Study Notes

1. Default authentication

The default login page appears when the pop.xml file is loaded into the SpringSecutrity dependency launcher, starts the project, and accesses the article list page. The default user name is required: user, and the password is derived from the console output, which is the most basic login

2. Memory authentication

Create a user-defined user name and password (the user name and password are written in the code and cannot be maintained)

  • Create a new SecurityConfig configuration class, inheritance WebSecurityConfigurerAdapter class, rewrite the configure (AuthenticationManagerBuilder auth) custom authentication
/* Enable security management configuration */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /* Custom authentication */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        /* Password compiler */
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        /*1. Memory-based authentication */
        // Add two account passwords
        auth.inMemoryAuthentication().passwordEncoder(encoder)
                .withUser("admin").password(encoder.encode("admin")).roles("admin")
                .and()
                .withUser("junko").password(encoder.encode("123456")).roles("common"); }}Copy the code

To start the project, you need to enter the account password defined above to log in. There are three tables, namely user, permission, and user-permission table

3. Use UserDetails for identity authentication

Create an interface to query users and their permissions

@Mapper
public interface TUserMapper {

 /* Query user information by user name */
@Select("select * from t_user where username=#{username}")
public TUser selectUserByUserName(String username);
}
Copy the code
@Mapper
public interface AuthorityMapper {
 /* Query user permissions based on user names */
public List<Authority> selectAuthorityByUserName(String username);
}
Copy the code

      
<! DOCTYPEmapper
        PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.junko.mapper.AuthorityMapper">

    <select id="selectAuthorityByUserName" resultType="net.junko.bean.Authority" parameterType="string">
        select a.* from t_user u,t_authority a,user_authority au where u.id=au.uid and a.id=au.aid and u.username=#{username}
    </select>
</mapper>
Copy the code

Write the UserDetailsServiceImpl implementation class

As mentioned above, to use the database query method for authorization authentication, you need to implement the UserDetailsService interface and rewrite the loadUserByUsername method

@Service
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    TUserMapper userMapper;
    @Autowired
    AuthorityMapper authorityMapper;

    /* according to the user name passed into the front-end login page, query the database corresponding user information and user permission, user information and permission encapsulation into the UserDetails object, give SpringSecurity for identity authentication */
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        /* Query user information and permission information by user name */
        TUser user = userMapper.selectUserByUserName(s);
        List<Authority> authorities = authorityMapper.selectAuthorityByUserName(s);

        /* Traversal encapsulates user permissions */
        List<SimpleGrantedAuthority>  authorityList = new ArrayList<>();
		for (int i=0; i<authorities.size(); i++) { authorityList.add(new SimpleGrantedAuthority(authorities.get(i).getAuthority()));
        }

        if(user! =null)
        {
            /* Encapsulate the user name, password, and user rights into a UserDetails object */
            UserDetails userDetails = new User(user.getUsername(),encoder.encode(user.getPassword()),authorityList);
            return userDetails;
        }
        else {
            throw new UsernameNotFoundException("User does not exist"); }}}Copy the code

Configure authentication against UserDetails within the SecurityConfig class

Comment out the in-memory authentication from previous 2 and inject UserDetailsServiceImpl

/* Enable security management configuration */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    /* Custom authentication */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        /* Password compiler */
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        /*1. Memory-based authentication */
// auth.inMemoryAuthentication().passwordEncoder(encoder)
// .withUser("admin").password(encoder.encode("admin")).roles("admin")
// .and()
// .withUser("cai").password(encoder.encode("123457")).roles("common");

        /*2. Use UserDetails for authentication */auth.userDetailsService(userDetailsService).passwordEncoder(encoder); }}Copy the code

Test the user information stored in the database when logging in

User Authorization Management

After the authentication mode is set up, you need to set some more Settings if you want to specify different permissions to access different pages, that is, to customize access control

  • Override the Configue (HttpSecurity HTTP) method in the SecurityConfig configuration class. If the user does not have permission to access a page, an error appears on page 403, indicating that the user can modify it based on his project.
/* Enable security management configuration */
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    UserDetailsServiceImpl userDetailsService;

    /* Custom authentication */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        /* Password compiler */
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

        /*1. Memory-based authentication */
// auth.inMemoryAuthentication().passwordEncoder(encoder)
// .withUser("admin").password(encoder.encode("admin")).roles("admin")
// .and()
// .withUser("cai").password(encoder.encode("123457")).roles("common");

        /*2. Use UserDetails for authentication */
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
    }


    /* Custom user permissions */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /* Custom access control */
        http.authorizeRequests()
                .antMatchers("/").permitAll()  // Allows access with "/"
                // Configure access permissions based on user permissions
                .antMatchers("/admin/**").hasAuthority("admin")
                .antMatchers("/common/**").hasAuthority("common") .and() .formLogin(); }}Copy the code

After setting user permissions, you can access pages in the/directory without authentication, and pages in the /admin/** directory need to be accessed by the user with admin permission, and /common/** can be accessed by the user with admin permission