第三节 SpringSecurity自定义登录验证

亮子 2021-07-19 02:56:56 17441 1 1 0

1、固定用户名密码

1)、定义密码算法

如果我们要是使用我们自己定义的用户密码,那么首先要定义密码的加密算法,目前的版本已经不支持明文密码了。密码加密算法的定义如下:

@Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

2)、设置密码算法和用户账号信息

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        log.info("configure:AuthenticationManagerBuilder = ");

        // 设置密码加密算法
        auth.inMemoryAuthentication().passwordEncoder(passwordEncoder);

        // 设置密码
        auth.inMemoryAuthentication().withUser("david").password(passwordEncoder.encode("123456")).authorities("select","add")
                .and()
                .withUser("admin").password(passwordEncoder.encode("123456")).authorities("select", "add", "update");
    }

2、自定义账号验证

1)、定义权限类

package com.shenmazong.demosecurity0718.config;

import lombok.Data;
import org.springframework.security.core.GrantedAuthority;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2021/7/19 10:20
 */

@Data
public class MyRole implements GrantedAuthority {
    private String roleName;

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

2)、自定义用户类

package com.shenmazong.demosecurity0718.config;

import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;
import java.util.List;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2021/7/19 10:22
 */

@Data
public class MyUserDetail implements UserDetails {

    private String userName;
    private String userPass;
    private List<MyRole> userRoles;

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return userRoles;
    }

    @Override
    public String getPassword() {
        return userPass;
    }

    @Override
    public String getUsername() {
        return userName;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

3)、账号验证的自定义实现类

实际上就是实现AuthenticationProvider接口

package com.shenmazong.demosecurity0718.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2021/7/19 10:36
 */

@Component
@Slf4j
public class MyAuthenticationProvider implements AuthenticationProvider {

    /**
     * @description 自定义验证用户名和密码
     * @author 军哥
     * @date 2021/7/19 10:54
     * @version 1.0
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        log.info("authenticate:来登录了");

        //--1 表单输入的用户名和密码
        String username = (String) authentication.getPrincipal();
        String password = (String) authentication.getCredentials();
        log.info("username={},password={}", username, password);

        if(!username.equals("david")) {
            throw new BadCredentialsException("用户不存在!");
        }

        if(!password.equals("123456")) {
            throw new BadCredentialsException("密码不正确!");
        }

        MyUserDetail user = new MyUserDetail();
        user.setUserName(username);
        user.setUserPass(password);

        MyRole myRole = new MyRole();
        myRole.setRoleName("select");

        ArrayList<MyRole> myRoles = new ArrayList<>();
        myRoles.add(myRole);

        user.setUserRoles(myRoles);


        return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
    }

    /**
     * @description 如果该AuthenticationProvider支持传入的Authentication对象,则返回true
     * @author 军哥
     * @date 2021/7/19 10:54
     * @version 1.0
     */
    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}

4)、使用自定义账号验证

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        log.info("configure:AuthenticationManagerBuilder = ");

        // 使用自定义的验证类
        auth.authenticationProvider(myAuthenticationProvider);
    }

完整配置类:

package com.shenmazong.demosecurity0718.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;

/**
 * @author 军哥
 * @version 1.0
 * @description: SpringSecurity配置类
 * @date 2021/7/18 17:45
 */

@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Resource
    MyAuthenticationProvider myAuthenticationProvider;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        log.info("configure:WebSecurity = ");
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                // 放行url
                .antMatchers("/login", "/index").permitAll()
                // 其他所有url请求都需要验证
                .anyRequest().authenticated()

                // 设定登录相关页面
                .and()
                .formLogin()
                .loginProcessingUrl("/process")
                .successForwardUrl("/success").
                failureForwardUrl("/failure")

                // 跨域請求关闭
                .and().csrf().disable()
                // 资源下载权限关闭
                .headers().frameOptions().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        log.info("configure:AuthenticationManagerBuilder = ");

        // 使用自定义的验证类
        auth.authenticationProvider(myAuthenticationProvider);
    }
}