基于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 {
@GetMapping
public 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 {
@Override
protected 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();
}
@Resource
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder getPassword() {
return new BCryptPasswordEncoder();
}
// 自定义用户的信息
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(getPassword());
}
}
4.service逻辑代码
@Service
public class MyUserDetailService implements UserDetailsService {
// 根据用户的名字 加载用户的信息
@Override
public 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.Driver
url: jdbc:mysql:///test01?serverTimezone=UTC
password: root
username: root
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-date-keys-as-timestamps: false
mvc:
pathmatch:
matching-strategy: ant_path_matcher
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:/mapper/*.xml
global-config:
db-config:
logic-not-delete-value: 1
logic-delete-value: 0
type-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_menu
where id in
(
select mid
from tab_role_menu
where 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 {
@Resource
private TabUserMapper userMapper;
@Resource
private TabUserRoleMapper userRoleMapper;
@Resource
private TabRoleMapper roleMapper;
@Resource
private TabMenuMapper menuMapper;
// 根据用户的名字 加载用户的信息
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// username 代表前端传递过来的名字
// 根据名字去数据库查询一下有没有这个用户的信息
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("username",username);
TabUser tabUser = userMapper.selectOne(queryWrapper);
if(tabUser != null) {
// 有值 查询用户对应的角色的id
QueryWrapper 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 查询rcode
List<TabRole> tabRoles = roleMapper.selectBatchIds(rids);
// 角色的修信息 角色管理 修改角色的名字
List<SimpleGrantedAuthority> collect = tabRoles.stream().map(tabRole -> new SimpleGrantedAuthority("ROLE_" + tabRole.getRcode())).collect(Collectors.toList());
// 根据角色的id 查询菜单的mcode
List<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;
}
}
调试接口进行测试