Springboot详解整合SpringSecurity实现全过程

2022-11-13 13:11:09 整合 详解 全过程

使用Basic认证模式

1、Maven依赖

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- SpringBoot整合WEB组件 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- springboot整合freemarker -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!-->spring-boot 整合security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

2、SecurityConfig 配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.inMemoryAuthentication().withUser("kaico_admin").password("kaico")
                .authorities("/");
        // 如果kaico_admin账户权限的情况 所有的接口都可以访问,如果kaico_add 只能访问addMember
        auth.inMemoryAuthentication().withUser("kaico_add").password("kaico")
                .authorities("/");
    }
    @Override
    protected void configure(httpsecurity Http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("
    @Bean
    public static NoOpPassWordEncoder passwordEncoder() {
        return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
    }
}

3、测试controller接口

@Controller
public class IndexController {
    
    @RequestMapping("/")
    public String index() {
        return "index";
    }
    @ResponseBody
    @RequestMapping("/addMember")
    public String addMember() {
        return "新增用户";
    }
    @ResponseBody
    @RequestMapping("/delMember")
    public String delMember() {
        return "删除用户";
    }
    @ResponseBody
    @RequestMapping("/updateMember")
    public String updateMember() {
        return "修改用户";
    }
    @ResponseBody
    @RequestMapping("/showMember")
    public String showMember() {
        return "查询用户";
    }
}

使用form表形式登录

在上面Basic认证模式的基础上修改SecurityConfig配置类,修改下面的方法

@Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置httpBasic Http协议认证
        http.authorizeRequests().antMatchers("
    @Select(" select * from sys_user where username = #{userName}")
    UserEntity findByUsername(@Param("userName") String userName);
    
    @Select(" select permission.* from sys_user user" + " inner join sys_user_role user_role"
            + " on user.id = user_role.user_id inner join "
            + "sys_role_permission role_permission on user_role.role_id = role_permission.role_id "
            + " inner join sys_permission permission on role_permission.perm_id = permission.id where user.username = #{userName};")
    List<PermissionEntity> findPermissionByUsername(@Param("userName") String userName);
}

实现springSecurity的接口UserDetailsService

@Component
@Slf4j
public class MemberUserDetailsService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.根据该用户名称查询在数据库中是否存在
        UserEntity userEntity = userMapper.findByUsername(username);
        if (userEntity == null) {
            return null;
        }
        // 2.查询对应的用户权限
        List<PermissionEntity> listPermission = userMapper.findPermissionByUsername(username);
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        listPermission.forEach(user -> {
            authorities.add(new SimpleGrantedAuthority(user.getPermTag()));
        });
        log.info(">>>authorities:{}<<<", authorities);
        // 3.将该权限添加到security
        userEntity.setAuthorities(authorities);
        return userEntity;
    }
}

密码加密工具

public class MD5Util {
	private static final String SALT = "kaico";
	public static String encode(String password) {
		password = password + SALT;
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		char[] charArray = password.toCharArray();
		byte[] byteArray = new byte[charArray.length];
		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = ((int) md5Bytes[i]) & 0xff;
			if (val < 16) {
				hexValue.append("0");
			}
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();
	}
}

SecurityConfig配置类

@Component
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MemberUserDetailsService memberUserDetailsService;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 设置用户账号信息和权限
        auth.userDetailsService(memberUserDetailsService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence rawPassword) {
                //对密码做加密
                return MD5Util.encode((String) rawPassword);
            }
            
            @Override
            public boolean matches(CharSequence charSequence, String s) {
                String rawPass = MD5Util.encode((String) charSequence);
                boolean result = rawPass.equals(s);
                return result;
            }
        });
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置权限
        http.authorizeRequests().antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/addMember").hasAnyAuthority("addMember")
                .antMatchers("/delMember").hasAnyAuthority("delMember")
                .antMatchers("/updateMember").hasAnyAuthority("updateMember")
                .antMatchers("/showMember").hasAnyAuthority("showMember")
                .antMatchers("/login").permitAll() //放行登录请求页面
                .antMatchers("/**").fullyAuthenticated()
                .and().formLogin().loginPage("/login").and().csrf().disable();
    }
}

整合完成,开始测试。

动态绑定数据库所有权限

在上面代码的基础上实现,上面是在代码中配置请求路径和权限标识的绑定,现在改成在数据库中动态配置。

SecurityConfig配置类

@Override
protected void configure(HttpSecurity http) throws Exception {
    //配置权限
    List<PermissionEntity> allPermission = permissionMapper.findAllPermission();
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlReGIStry
            expressionInterceptUrlRegistry = http.authorizeRequests();
    allPermission.forEach((permission) -> {
        expressionInterceptUrlRegistry.antMatchers(permission.getUrl()).
                hasAnyAuthority(permission.getPermTag());
    });
    expressionInterceptUrlRegistry.antMatchers("/login").permitAll()
            .antMatchers("/**").fullyAuthenticated()
            .and().formLogin().loginPage("/login").and().csrf().disable();
}

到此这篇关于Springboot详解整合SpringSecurity实现全过程的文章就介绍到这了,更多相关Springboot SpringSecurity内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关文章