SpringSecurity - Authentication + Authorization Code Implementation

Authentication + Authorization Code Implementation

Spring Security is a security framework based on Spring AOP and Servlet filters.It provides a comprehensive security solution while handling authentication and authorization at the Web request and method call levels.

Previously, I blogged about the theory of authentication and authorization. Understanding Rights Management

1. SpringSceurity Workflow

Look for a picture on the Internet and find it very good and easy to understand.Otherwise, the source flowchart is difficult to understand.

Picture address: address You can zoom in and see more clearly on a single machine

To understand this diagram, it is recommended that you look at this blog, because this diagram requires custom M.. classes, which are explained in the article, so you can better understand the point.

Spring Boot Security Details


2. Authentication + Authorization Code

Only a few core codes are shown here, with the full code on github.

1. UserDetails interface

User interface in Security, which we customize the user class to implement to inject the current user's name, password, and role into security.It also contains other information, such as whether the current user is out of date.

Whether the account is locked, etc.

Define your own User to implement this interface

public class User implements UserDetails {
    private String username;
    private String password;
    private List<Role> roles;
    /**
     * Get User Name
     */
    @Override
    public String getUsername() {
        return username;
    }
    /**
     * Get Password
     */
    @Override
    public String getPassword() {
        return password;
    }
    /**
     * User's permission set, ROLE_needs to be added by defaultprefix
     */
    @Override
    @JsonIgnore
    public List<GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<>();
        for (Role role : roles) {
            authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
        }
        return authorities;
    }
    /**
     * Is Account Expired
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonExpired() {
        return true;
    }
    /**
     * Is Account Locked
     */
    @Override
    @JsonIgnore
    public boolean isAccountNonLocked() {
        return true;
    }
    /**
     * Does the voucher expire
     */
    @Override
    @JsonIgnore
    public boolean isCredentialsNonExpired() {
        return true;
    }
    /**
     * Is User Available
     */
    @Override
    public boolean isEnabled() {
        return true;
    }  
}

2,UserDetailsService

User Service in Security. Custom user service classes need to implement this interface.There is only one way to implement this interface, which is to get user information by user name.Here is also the interactive acquisition with the database

A place for user authentication and authorization information.

@Service
@Slf4j
public class UserService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        //TODO should normally query the database for user and user permissions
//        User user = userMapper.loadUserByUsername(userName);
//        List<Role> roles = rolesMapper.getRolesByUid(user.getId());
//        user.setRoles(roles);
        log.info("Logon username: {}", userName);
        //Password password queried by user name must be encrypted Here clear text password is 123456
        String password = "e10adc3949ba59abbe56e057f20f883e";
        //User Corresponding Permissions
        List<Role> roles = Lists.newArrayList(new Role(1L, "Teacher"), new Role(2L, "Student"));
        User user = new User(userName, password, roles);
        return user;
    }
}

Note that the clear text password here is 123456, which means the user can enter this to complete the authentication.If authorized, the current user has two roles as a teacher and a student.This will be used in the following tests.

3,WebSecurityConfigurerAdapter

It is the Java configuration class for Spring Security.Create class SecurityConfiguration inherits WebSecurityConfigurerAdapter for all security-related matters in our application(

All url s, validate username passwords, form redirection, etc.) are controlled.

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 1,Configuring authentication information, AuthenticationManagerBuilder is the class that builds AuthenticationManager. We only need to configure user information to this class.
     *    The corresponding Authentication Manager can be generated, which is mentioned as the manager of user identity and the entry point for authentication, so we need to configure this configuration to provide real user identity for security.
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    }
    /**
     * 2,Configure Security's authentication policy, with each module configuration ending with and.This is also the most complex
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    }
    /**
     * 3,This configuration method is used to configure how static resources are handled, using Ant matching rules.Is an interface that can be accessed directly without authentication
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
    }
}

Complete example

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;
    /**
     * Password verifier
     */
    @Autowired
    private PassWordEncorder passWordEncorder;
    /**
     * Success Processor
     */
    @Autowired
    private AuthenctiationSuccessHandler authenctiationSuccessHandler;

    /**
     * Failure Processor
     */
   @Autowired
   private AuthenctiationFailHandler authenctiationFailHandler;
   /**
    * Injecting user information into Security
    */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passWordEncorder);
    }
    /**
     * Configuration Rules
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //Turn on login configuration
        http.authorizeRequests()
                // Accessible after login
                .antMatchers("/no-authorize").authenticated()
                // Principal role privileges are required after landing
                .antMatchers("/need-authorize").hasRole("Principal")
                // The other paths are accessible after login
                .anyRequest().authenticated()
                .and().formLogin()
                // Defines a login page, which is automatically jumped to when you access an interface that requires login before it can be accessed
                .loginPage("/login_page")
                //Processors Logged on Successfully
                .successHandler(authenctiationSuccessHandler)
                //Processors with failed login
                .failureHandler(authenctiationFailHandler)
                // Logon Processing Interface
                .loginProcessingUrl("/login")
                // Define the key of the user name at login, defaulting to username
                .usernameParameter("username")
                //Define the key of the user's password at login, defaulting to password
                .passwordParameter("password").permitAll()
                .and().logout()
                ////All forms login-related interface systems pass directly through
                .permitAll()
                .and().csrf().disable().exceptionHandling().accessDeniedHandler(getAccessDeniedHandler());
    }

    /**
     * No authentication is required for paths under/static/
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/no-login");
    }

    /**
     * User Unauthenticated Exception Interception
     */
    @Bean
    AccessDeniedHandler getAccessDeniedHandler() {
        return new AuthenticationAccessDeniedHandler();
    }
}

Notice that there are three paths configured for testing.

1. /no-login interface can be accessed directly without authentication
 2. /no-authorize requires authentication but does not require authorization to access
 3. /need-authorize first requires authentication. Pass also requires authorization where the principal's role is required to access the interface, but we test that users only have teachers and students and therefore do not have access to the interface

This interface is tested separately.


3. Testing

1. Interface Provision

@RestController
public class TestController {

    /**
     * 1,Access without login
     */
    @RequestMapping(value = "/no-login")
    public ServiceResponse noLogin() {
        return ServiceResponse.success("Welcome to an interface that does not require a login");
    }
    /**
     * 2,Log on only, no authentication interface allowed
     */
    @RequestMapping(value = "/no-authorize")
    public ServiceResponse needAuthorize(){
        return ServiceResponse.success("Logged on without authorization");
    }
    /**
     * 3,Logon+Related Authentication Interface
     */
    @RequestMapping(value = "/need-authorize")
    public ServiceResponse noAuthorize() {
        return ServiceResponse.success("Land+Authorization succeeded");
    }
    /**
     * @Description: If you automatically jump to this page, indicating that the user is not logged in, return to the appropriate prompt
     */
    @RequestMapping("/login_page")
    public ServiceResponse loginPage() {
        return  ServiceResponse.failure("001", "Not logged in yet, please log in!");
    }
}

2. Unlogged access to no-login and no-authorize interfaces

no-login interface

Apparently no logon request for this interface succeeded!

no-authorize interface

No login access failure, configuring above to jump to login_if user is not authenticatedPage interface, so this returns'Not yet logged in, please log in!'

3. Access the no-authorize and need-authorize interfaces after login

Log on first

Request parameters for logon path / login include username and password based on the configuration above

Note that a post request is required here.

no-authorize interface

Log in and you'll be able to access it.

need-authorize interface

Although the login was successful, the access failed because the interface required a principal role, which was previously only configured for the user as a teacher and a student.


Reference resources

1,Security Framework in SpringSide 3

2,Overview of how Spring Security works

3,Spring Boot Security Details Very complimentary



When someone scolds me for being fat, I get angry because I admit I am fat in my heart.I get funny when people say I'm short because I know I can't be short.That's why we get angry at other people's attacks.
Those who attack my shield are the spears within me (17)

Keywords: Spring Database github Java

Added by john_nyc on Thu, 04 Jun 2020 04:08:57 +0300