基于springBoot项目
引入依赖配置文件
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>
快速上手
不连接数据库
1.创建用户实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserTest {private String username;private String password;
}
2.Controller层(测试权限)
@RestController
@RequestMapping("/test")
public class MyController {@GetMappingpublic String test01() {return "hello security!!!";}
}
@RestController
public class SuccessController {@GetMapping("success")public String test02() {return "success";}@Secured({"ROLE_ADMIN"})@RequestMapping("testSecured")public String test03() {return "testSecured";}@PreAuthorize("hasAnyAuthority('testpath')")@RequestMapping("")public String test04() {return "testSecured02";}
}
3.security配置文件
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {
// 配置登录的form表单
// 路径前面必须加/http.formLogin().loginPage("/login.html").loginProcessingUrl("/userlogin").usernameParameter("myname").passwordParameter("mypwd").defaultSuccessUrl("/success");http.authorizeRequests().antMatchers("/login.html","/userlogin","/").permitAll();// 其他的路径 都需要认证http.authorizeRequests().anyRequest().authenticated();
// 权限不允许的时候http.exceptionHandling().accessDeniedPage("/403.html");// csrf 方便html 文件 能够通过http.csrf().disable();}@Resourceprivate UserDetailsService userDetailsService;@Beanpublic PasswordEncoder getPassword() {return new BCryptPasswordEncoder();}// 自定义用户的信息@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService).passwordEncoder(getPassword());}
}
4.service逻辑代码
@Service
public class MyUserDetailService implements UserDetailsService {// 根据用户的名字 加载用户的信息@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// username 代表前端传递过来的名字BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String encode = passwordEncoder.encode("root");UserTest userTest = new UserTest("root", encode);if(username.equals(userTest.getUsername())) {List<SimpleGrantedAuthority> authorities = new ArrayList<>();
// authorities 代表所有资源的信息authorities.add(new SimpleGrantedAuthority("testpath"));authorities.add(new SimpleGrantedAuthority("ROLE_USER"));return new User(username,encode,authorities);}return null;}
}
连接数据库(权限实例)
sql文件顶部资源下载
1.引入相关依赖
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- mp--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><!-- 自动生成--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.3</version></dependency><!-- 模板--><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId></dependency>
2.通过mybatis-plus快速生成代码
public class MyTest {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql:///test01?useSSL=false","root","root")// 全局配置.globalConfig((scanner, builder) -> builder.author("hp").outputDir("D:\\Idea-spring-security\\demo01\\src\\main\\java"))// 包配置.packageConfig((scanner, builder) ->builder.parent("com.security").pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\Idea-spring-security\\demo01\\src\\main\\resources\\mapper")))// 策略配置.strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all"))).controllerBuilder().enableRestStyle().enableHyphenStyle().entityBuilder().enableLombok().addTableFills(new Column("create_time", FieldFill.INSERT)).build())/*模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker.templateEngine(new BeetlTemplateEngine()).templateEngine(new FreemarkerTemplateEngine())*/.execute();// 处理 all 情况}protected static List<String> getTables(String tables) {return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));}
}
3.application 文件
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql:///test01?serverTimezone=UTCpassword: rootusername: rootjackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8serialization:write-date-keys-as-timestamps: falsemvc:pathmatch:matching-strategy: ant_path_matchermybatis-plus:configuration:map-underscore-to-camel-case: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:/mapper/*.xmlglobal-config:db-config:logic-not-delete-value: 1logic-delete-value: 0type-aliases-package: com.security.entity
4.TabMenuMapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.security.mapper.TabMenuMapper"><select id="selectCodeByRids" resultType="TabMenu">select *from tab_menuwhere id in(select midfrom tab_role_menuwhere rid in<foreach collection="list" item="rid" open="(" close=")" separator=",">#{rid}</foreach>)</select>
</mapper>
5.TabMenuMapper
public interface TabMenuMapper extends BaseMapper<TabMenu> {List<TabMenu> selectCodeByRids(List<Integer> rids);
}
6.修改service文件
@Service
public class MyUserDetailService implements UserDetailsService {@Resourceprivate TabUserMapper userMapper;@Resourceprivate TabUserRoleMapper userRoleMapper;@Resourceprivate TabRoleMapper roleMapper;@Resourceprivate TabMenuMapper menuMapper;// 根据用户的名字 加载用户的信息@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// username 代表前端传递过来的名字
// 根据名字去数据库查询一下有没有这个用户的信息QueryWrapper queryWrapper = new QueryWrapper();queryWrapper.eq("username",username);TabUser tabUser = userMapper.selectOne(queryWrapper);if(tabUser != null) {
// 有值 查询用户对应的角色的idQueryWrapper queryWrapper1 = new QueryWrapper();queryWrapper1.eq("uid",tabUser.getId());List<TabUserRole> tabUserRoles = userRoleMapper.selectList(queryWrapper1);List<Integer> rids = tabUserRoles.stream().map(tabUserRole -> tabUserRole.getRid()).collect(Collectors.toList());
// 根据角色的id 查询rcodeList<TabRole> tabRoles = roleMapper.selectBatchIds(rids);
// 角色的修信息 角色管理 修改角色的名字List<SimpleGrantedAuthority> collect = tabRoles.stream().map(tabRole -> new SimpleGrantedAuthority("ROLE_" + tabRole.getRcode())).collect(Collectors.toList());
// 根据角色的id 查询菜单的mcodeList<TabMenu> menus = menuMapper.selectCodeByRids(rids);List<SimpleGrantedAuthority> resources = menus.stream().map(tabMenu -> new SimpleGrantedAuthority(tabMenu.getMcode())).collect(Collectors.toList());
// 将角色的所有信息,和资源信息合并在一起List<SimpleGrantedAuthority> allresource = Stream.concat(collect.stream(), resources.stream()).collect(Collectors.toList());return new User(username, tabUser.getPassword(), allresource);}return null;}
}
7.获取用户的信息
/*
* 获取当前登录的用户的信息
* */
@RestController
public class UserController {@GetMapping("user1")@PreAuthorize("hasAnyAuthority('user:add')")public Object getUser(Principal principal) {return principal;}@GetMapping("user2")public Object getUser2(Authentication authentication){return authentication;}@GetMapping("user3")public Object getUser3() {Authentication authentication = SecurityContextHolder.getContext().getAuthentication();return authentication;}
}
调试接口进行测试