1.创建一个spring-boot项目
2.导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
3.配置
3.1
@Configuration public class SecurityConfig { @Bean public Realm shiroRealm(){ return new ShiroRealm(); } @Bean public ShiroFilterChainDefinition shiroFilterChainDefinition(){ DefaultShiroFilterChainDefinition sfcd= new DefaultShiroFilterChainDefinition(); sfcd.addPathDefinition("/","anon"); sfcd.addPathDefinition("/login","anon"); sfcd.addPathDefinition("/login.html","anon"); sfcd.addPathDefinition("/css","anon"); sfcd.addPathDefinition("/js","anon"); sfcd.addPathDefinition("html","anon"); sfcd.addPathDefinition("/logout","logout"); sfcd.addPathDefinition("/**","user"); return sfcd; } @Bean public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){ DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setUsePrefix(true); return defaultAdvisorAutoProxyCreator; } }
3.2.yml配置
spring: application: name: shiro_boot datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/shiro?characterEncoding=utf8&useSSL=false&serverTimezone=UTC password: 123456 username: root jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8 mvc: format: date: yyyy-MM-dd HH:mm:ss mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl map-underscore-to-camel-case: true type-aliases-package: com.woniuxuy.shiro_boot.model shiro: loginUrl: /login.html server: port: 80
4.实现shiroRealm
public class ShiroRealm extends AuthorizingRealm { private static JdbcTemplate jdbcTemplate=null; @Resource UserTableMapper userTableMapper; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { //授权的前提是 认证 => 得到用户信息 //授权信息包含 角色 + 权限 //授权: 根据用户去查询 角色 + 权限 => 入参:用户 出参:角色 + 权限 UserTable user = (UserTable) principalCollection.getPrimaryPrincipal(); System.out.println(">>>>>>>>1 "+user); // 根据用户查询角色 List<RoleTable> roleList = jdbcTemplate.query("select r.* from user_table u join user_roles ur on u.user_id = ur.user_id join role_table r on r.role_id = ur.rolse_id where u.user_id = ?" , new BeanPropertyRowMapper<RoleTable>(RoleTable.class) , user.getUserId()); System.out.println(">>>>>>>>2 "+roleList); Set<String> strRoles = roleList.stream() .map(r -> r.getRole()) .collect(Collectors.toSet()); System.out.println(">>>>>>>>3 "+strRoles); //根据角色查询权限 1,2 String joined = roleList.stream().map(role -> "" + role.getRoleId()).collect(Collectors.joining(",")); System.out.println(">>>>>>>>4 "+joined); List<String> permissions = jdbcTemplate.query("sselect p.permission from permission_roles rp join permission_table p on rp.permission_id=p.permission_id\n" + "where rp.rolse_id in (" + joined + ")", new SingleColumnRowMapper<>(String.class)); System.out.println(">>>>>>>>5 "+permissions); SimpleAuthorizationInfo authzInfo = new SimpleAuthorizationInfo(); authzInfo.setRoles(strRoles); authzInfo.setStringPermissions(new HashSet<>(permissions)); System.out.println(">>>>>>>>6 "+authzInfo); return authzInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("进入获取认证信息方法:"+token); Object user = token.getPrincipal(); //查询用户 QueryWrapper<UserTable> wrapper = new QueryWrapper<>(); wrapper.eq(user!=null,"user_name",user); UserTable userTable = userTableMapper.selectOne(wrapper); if(userTable==null){ throw new UnknownAccountException(user+"用户不存在"); } //获取到用户名 Object username = token.getPrincipal(); //查询用户 //适配返回对象, 用户、密码、Realm名字 return new SimpleAuthenticationInfo(userTable,userTable.getUserPwd(),ShiroRealm.class.getName()); } }
5.登录接口
@RestController @Slf4j public class LoginController { @PostMapping("/login") public Result login(String username, String password){ Subject subject = SecurityUtils.getSubject(); subject.login(new UsernamePasswordToken(username,password)); return Result.success(); } @GetMapping("/pay") public Result pay(){ return Result.success(); } }