网站开发环境有哪些php,模版网站建设步骤详解,兰州市科协网站,网站安全建设论文1.先了解RBAC 是什么
RBAC(Role-Based Access control) #xff0c;也就是基于角色的权限分配解决方案 2.数据库读取用户信息和授权信息
1.上篇用户名好授权等信息都是从内存读取实际情况都是从数据库获取#xff1b; 主要设计两个类 UserDetails和UserDetailsService 看下…1.先了解RBAC 是什么
RBAC(Role-Based Access control) 也就是基于角色的权限分配解决方案 2.数据库读取用户信息和授权信息
1.上篇用户名好授权等信息都是从内存读取实际情况都是从数据库获取 主要设计两个类 UserDetails和UserDetailsService 看下继承图 不难看出 InMemoryUserDetailsManager 继承UserDetailsService
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.security.core.userdetails;import java.io.Serializable;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;public interface UserDetails extends Serializable {Collection? extends GrantedAuthority getAuthorities();String getPassword();String getUsername();boolean isAccountNonExpired();boolean isAccountNonLocked();boolean isCredentialsNonExpired();boolean isEnabled();
}
不难看出UserDetails 也就是和普通的pojo 综上所述只需要写一个类实现UserDetailsService 接口的方法和写一个普通的javaBean 继承UserDetails交给spring 容器也就完成了自定义用户的信息
3.创建5张表用户表角色表权限表用户角色表角色权限表
create table sys_user (id int auto_increment primary key ,
name varchar(50) unique not null comment 用户名 ,password varchar(200) comment 密码,
is_expired int default 1 comment 登陆是否过期,
is_locked int default 1 comment 账号是否锁定,
is_enable int default 1 comment 账号是否可用,
credentials_expired int default 1 comment 凭证过期);
select * from sys_user;添加两条数据测试 密码都是123456
create table sys_roles (id int auto_increment primary key ,name varchar(200) not null comment 角色名称);create table sys_authority(id int auto_increment primary key ,authority varchar(120) not null
);备注老师和学生老师可以删除作业。查看作业。修改作业 学生拥有查看修改作业 create table sys_user_roles (user_id int not null comment 用户id,roles_id int not null comment 校色id
);为用户张三和小李分配角色 张三拥有学生的权限小李拥有老师权限
create table sys_roles_authority (id int not null comment 角色id,authority_id int not null comment 权限id
);添加两个角色。角色1 学生 角色2 老师
3.定义一个类实现UserDetailsService交给spring 容器调度
主要在这个方法loadUserByUsername 从数据库读取用户的登录信息和权限信息
package com.example.testsecurity.service;import com.example.testsecurity.mapper.UserMapper;
import com.example.testsecurity.pojo.MyUser;
import com.example.testsecurity.pojo.User;
import com.example.testsecurity.pojo.UserAuthority;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import java.util.Objects;Service
Slf4j
public class MyUserService implements UserDetailsService {Autowiredprivate UserMapper userMapper;Autowiredprivate UserAuthorityService userAuthorityService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user userMapper.findUserByName(username);UserAuthority userAuthority userAuthorityService.findAuthorByUserId(user.getId());log.info(userAuthority.getAuthority());if (Objects.isNull(user)) {throw new UsernameNotFoundException(用户名不存在);}log.info(user username);MyUser myUser new MyUser(user, userAuthority);return myUser;}
}
4.定义一个类实现UserDetails
实体类
package com.example.testsecurity.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;Data
AllArgsConstructor
NoArgsConstructor
Component
public class User {private int id;private String name;private int roleId;JsonIgnoreprivate String password; //忽略返回密码private int isExpired;private int isLocked;private int isEnable;private int credentialsExpired;}
package com.example.testsecurity.pojo;import com.example.testsecurity.service.UserAuthorityService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;//自定义用户信息
Component
AllArgsConstructor
Data
NoArgsConstructor
Slf4j
public class MyUser implements UserDetails {private User user;private UserAuthority userAuthority;Overridepublic Collection? extends GrantedAuthority getAuthorities() {String[] authorities userAuthority.getAuthority().split(,); //由于数据库中authority字段里面是用,来分隔每个权限ListSimpleGrantedAuthority simpleGrantedAuthorities new ArrayList();for (String role : authorities) {simpleGrantedAuthorities.add(new SimpleGrantedAuthority(role));}log.info(simpleGrantedAuthorities.get(0).getAuthority());return simpleGrantedAuthorities;}Overridepublic String getPassword() {String password user.getPassword();user.setPassword(null);// 擦除密码防止传到前端return password;}Overridepublic String getUsername() {return user.getName();}Overridepublic boolean isAccountNonExpired() {return user.getIsExpired() 1;}Overridepublic boolean isAccountNonLocked() {return user.getIsLocked() 1;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return user.getIsEnable() 1;}
}
package com.example.testsecurity.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;Data
AllArgsConstructor
NoArgsConstructor
public class UserAuthority {private int id;private String authority;}
5.编写测试controller
package com.example.testsecurity.controller;import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;RestController
RequestMapping(/test)
public class TestController {GetMapping(/lookZy)PreAuthorize(hasAuthority(look:zy))public String lookZy() {return 查看作业;}GetMapping(/editZy)PreAuthorize(hasAuthority(edit:zy))public String editZy() {return 编辑作业;}GetMapping(/delZy)PreAuthorize(hasAnyAuthority(del:zy))public String delZy() {return 删除作业;}
}
6.编写配置类并开启方法授权
package com.example.testsecurity.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.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;//从 Spring Security 5.7.0-M2开始 WebSecurityConfigurerAdapter 被标记为过期鼓励用户转向基于组件的 security 配置
Configuration
Slf4j
//全局方法授权EnableWebSecurity // 启用SpringSecurityEnableMethodSecurity
public class SecurityConfiguration {//认证成功处理器Autowiredprivate AuthorSuccesssHandler authorSuccesssHandler;Autowired//认证失败处理器private AuthorFailHandler authorFailHandler;//退出登录处理器Autowiredprivate AppLoginOutHandler appLoginOutHandler;//访问拒绝处理器Autowiredprivate AppAcessDeiedHandler appAcessDeiedHandler;Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(authorizationManagerRequestMatcherRegistry - authorizationManagerRequestMatcherRegistry.anyRequest().authenticated());http.formLogin().successHandler(authorSuccesssHandler)//认证成功.failureHandler(authorFailHandler)//认证失败.permitAll();http.logout().logoutSuccessHandler(appLoginOutHandler); //退出登录http.exceptionHandling().accessDeniedHandler(appAcessDeiedHandler);//访问资源失败return http.build();}// Bean
// public WebSecurityCustomizer webSecurityCustomizer() {
// return (web) - web.ignoring().requestMatchers(/test/**);
// }Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
7.登录测试查看用户信息并测试权限 张三用户信息 小李信息
张三学生、和小李都可以访问的接口 小李可以访问的 张三访问不了资源 备注两个mapper代码
package com.example.testsecurity.mapper;import com.example.testsecurity.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;Mapper
public interface UserMapper {Select(select * from sys_user where name#{username})User findUserByName(String username);}package com.example.testsecurity.mapper;import com.example.testsecurity.pojo.UserAuthority;
import org.apache.ibatis.annotations.Mapper;Mapper
public interface UserAuthorityMapper {UserAuthority findAuthorByUserId(Integer userId);
}
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd
!-- namespace等于mapper接口类的全限定名,这样实现对应 --
mapper namespacecom.example.testsecurity.mapper.UserAuthorityMapperselect idfindAuthorByUserId resultTypecom.example.testsecurity.pojo.UserAuthoritySELECT * FROM sys_authorityWHERE id(SELECT authority_id from sys_roles_authorityWHERE id(SELECT roles_id FROM sys_user_rolesWHERE user_id#{userId}));/select/mapper