[java] Shiro 框架学习 (二)Spring Boot 整合

梦里梦外; 2022-02-27 03:24 334阅读 0赞

环境

开发工具:IDEA

jdk版本:jdk1.8

创建项目

1.新建spring-boot项目

项目结构:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDkwMjUyNw_size_16_color_FFFFFF_t_70

2.导包 pom.xml文件

添加spring-boot 父级依赖,maven用户可用通过继承parent项目来获得一些合理的默认配置

  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>1.5.2.RELEASE</version>
  5. </parent>

导入spring-boot快速搭建web项目依赖包和集成shiro框架的依赖包

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-data-jpa</artifactId>
  9. <version>1.5.6.RELEASE</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-autoconfigure</artifactId>
  14. <version>1.5.6.RELEASE</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>mysql</groupId>
  18. <artifactId>mysql-connector-Java</artifactId>
  19. <version>5.1.46</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.apache.shiro</groupId>
  23. <artifactId>shiro-spring</artifactId>
  24. <version>1.3.2</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>com.alibaba</groupId>
  28. <artifactId>druid</artifactId>
  29. <version>1.1.4</version>
  30. </dependency>
  31. </dependencies>

添加spring - boot 支持maven

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-maven-plugin</artifactId>
  6. </plugin>
  7. </plugins>
  8. </build>

3.配置application.yml 文件,springboot项目所有配置都在该文件中完成

  1. server:
  2. port: 8082
  3. spring:
  4. datasource:
  5. driver-class-name: com.mysql.jdbc.Driver
  6. url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8
  7. username: root
  8. password: root
  9. type: com.alibaba.druid.pool.DruidDataSource
  10. jpa:
  11. show-sql: true
  12. hibernate:
  13. ddl-auto: update
  14. http:
  15. encoding:
  16. charset: utf-8
  17. enabled: true

4.创建用户,角色,权限实体类,shiro权限控制必须有这个三个实体类(表)

  1. User
  2. package com.ztwow.springshiro.entity;
  3. import javax.persistence.*;
  4. import java.util.List;
  5. /**
  6. * user
  7. * 用户实体类
  8. *
  9. * */
  10. @Entity
  11. public class User {
  12. @Id
  13. @GeneratedValue(strategy = GenerationType.AUTO)
  14. private Long id;
  15. @Column(unique = true)
  16. private String name;
  17. private Integer password;
  18. @OneToMany(cascade = CascadeType.ALL,mappedBy = "user")
  19. private List<Role> roles;
  20. public Long getId() {
  21. return id;
  22. }
  23. public void setId(Long id) {
  24. this.id = id;
  25. }
  26. public String getName() {
  27. return name;
  28. }
  29. public void setName(String name) {
  30. this.name = name;
  31. }
  32. public List<Role> getRoles() {
  33. return roles;
  34. }
  35. public void setRoles(List<Role> roles) {
  36. this.roles = roles;
  37. }
  38. public Integer getPassword() {
  39. return password;
  40. }
  41. public void setPassword(Integer password) {
  42. this.password = password;
  43. }
  44. }
  45. Role
  46. package com.ztwow.springshiro.entity;
  47. import javax.persistence.*;
  48. import java.util.List;
  49. /**
  50. * role
  51. * 角色实体类
  52. *
  53. * */
  54. @Entity
  55. public class Role {
  56. @Id
  57. @GeneratedValue(strategy = GenerationType.AUTO)
  58. private Long id;
  59. private String roleName;
  60. @ManyToOne(fetch = FetchType.EAGER)
  61. private User user;
  62. @OneToMany(cascade = CascadeType.ALL,mappedBy = "role")
  63. private List<Permission> permissions;
  64. public Long getId() {
  65. return id;
  66. }
  67. public void setId(Long id) {
  68. this.id = id;
  69. }
  70. public String getRoleName() {
  71. return roleName;
  72. }
  73. public void setRoleName(String roleName) {
  74. this.roleName = roleName;
  75. }
  76. public User getUser() {
  77. return user;
  78. }
  79. public void setUser(User user) {
  80. this.user = user;
  81. }
  82. public List<Permission> getPermissions() {
  83. return permissions;
  84. }
  85. public void setPermissions(List<Permission> permissions) {
  86. this.permissions = permissions;
  87. }
  88. }
  89. permission
  90. package com.ztwow.springshiro.entity;
  91. import javax.persistence.*;
  92. /**
  93. * permission
  94. * 权限实体类
  95. *
  96. * */
  97. @Entity
  98. public class Permission {
  99. @Id
  100. @GeneratedValue(strategy = GenerationType.AUTO)
  101. private Long id;
  102. private String permission;
  103. @ManyToOne(fetch = FetchType.EAGER)
  104. private Role role;
  105. public Long getId() {
  106. return id;
  107. }
  108. public void setId(Long id) {
  109. this.id = id;
  110. }
  111. public String getPermission() {
  112. return permission;
  113. }
  114. public void setPermission(String permission) {
  115. this.permission = permission;
  116. }
  117. public Role getRole() {
  118. return role;
  119. }
  120. public void setRole(Role role) {
  121. this.role = role;
  122. }
  123. }
  1. 持久层接口和实现类

使用JPA操作数据库:jpa学习

  1. #baseDao 接口 继承JPA动态查询和分页
  2. package com.ztwow.springshiro.dao;
  3. import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
  4. import org.springframework.data.repository.NoRepositoryBean;
  5. import org.springframework.data.repository.PagingAndSortingRepository;
  6. import java.io.Serializable;
  7. @NoRepositoryBean
  8. public interface BaseDao<T,I extends Serializable> extends PagingAndSortingRepository<T,I>, JpaSpecificationExecutor<T> {
  9. }
  10. #User 接口 实现baseDao
  11. package com.ztwow.springshiro.dao;
  12. import com.ztwow.springshiro.entity.User;
  13. public interface UserDao extends BaseDao<User,Long>{
  14. User findByName(String name);
  15. }
  16. #Role 接口实现baseDao
  17. package com.ztwow.springshiro.dao;
  18. import com.ztwow.springshiro.entity.Role;
  19. public interface RoleDao extends BaseDao<Role,Long>{
  20. }
  1. 编写业务层接口和实现类

    业务层接口

    package com.ztwow.springshiro.service;

    import com.ztwow.springshiro.entity.Role;
    import com.ztwow.springshiro.entity.User;

    import java.util.Map;

    public interface ILoginService {

    1. User addUser(Map<String,Object> map);
    2. Role addRole(Map<String,Object> map);
    3. User findByName(String name);

    }

  1. #实现类
  2. package com.ztwow.springshiro.service.impl;
  3. import com.ztwow.springshiro.dao.RoleDao;
  4. import com.ztwow.springshiro.dao.UserDao;
  5. import com.ztwow.springshiro.entity.Permission;
  6. import com.ztwow.springshiro.entity.Role;
  7. import com.ztwow.springshiro.entity.User;
  8. import com.ztwow.springshiro.service.ILoginService;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Service;
  11. import javax.transaction.Transactional;
  12. import java.util.ArrayList;
  13. import java.util.List;
  14. import java.util.Map;
  15. @Service
  16. @Transactional
  17. public class LoginServiceImlp implements ILoginService {
  18. @Autowired
  19. private UserDao userDao;
  20. @Autowired
  21. private RoleDao roleDao;
  22. //添加用户
  23. @Override
  24. public User addUser(Map<String, Object> map) {
  25. User user = new User();
  26. user.setName(map.get("username").toString());
  27. user.setPassword(Integer.valueOf(map.get("password").toString()));
  28. userDao.save(user);
  29. return user;
  30. }
  31. //添加角色
  32. @Override
  33. public Role addRole(Map<String, Object> map) {
  34. User user = userDao.findOne(Long.valueOf(map.get("userId").toString()));
  35. Role role = new Role();
  36. role.setRoleName(map.get("roleName").toString());
  37. role.setUser(user);
  38. Permission permission1 = new Permission();
  39. permission1.setRole(role);
  40. permission1.setPermission("create");
  41. Permission permission2 =new Permission();
  42. permission2.setPermission("update");
  43. permission2.setRole(role);
  44. List<Permission> permissions = new ArrayList<Permission>();
  45. permissions.add(permission1);permissions.add(permission2);
  46. role.setPermissions(permissions);
  47. roleDao.save(role);
  48. return role;
  49. }
  50. //通过用户名查询用户
  51. @Override
  52. public User findByName(String name){
  53. return userDao.findByName(name);
  54. }
  55. }

7.Shiro自定义配置类,通过@Bean注解的方式代替springMVC的XMl方式配置

  1. package com.ztwow.springshiro.config;
  2. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
  3. import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
  4. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.apache.shiro.mgt.SecurityManager;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. @Configuration
  11. public class ShiroConfiguration {
  12. //加入自己的验证方式到容器
  13. @Bean
  14. public MyShiroRealm myShiroRealm(){
  15. MyShiroRealm myShiroRealm = new MyShiroRealm();
  16. return myShiroRealm;
  17. }
  18. //权限管理,配置主要是Realm的管理认证
  19. @Bean
  20. public SecurityManager securityManager(){
  21. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
  22. securityManager.setRealm(myShiroRealm());
  23. return securityManager;
  24. }
  25. //Filter工厂,(添加)设置对应的过滤条件和跳转条件
  26. @Bean
  27. public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
  28. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
  29. shiroFilterFactoryBean.setSecurityManager(securityManager);
  30. Map<String,String> map = new HashMap<String, String>();
  31. //登出
  32. map.put("/logout","logout");
  33. //对所有用户认证
  34. map.put("/**","authc");
  35. //登录
  36. shiroFilterFactoryBean.setLoginUrl("/login");
  37. //首页
  38. shiroFilterFactoryBean.setSuccessUrl("/index");
  39. //错误页面,认证不通过跳转
  40. shiroFilterFactoryBean.setUnauthorizedUrl("/error");
  41. shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
  42. return shiroFilterFactoryBean;
  43. }
  44. //加入注解的使用,不加入这个注解不生效
  45. @Bean
  46. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
  47. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
  48. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
  49. return authorizationAttributeSourceAdvisor;
  50. }
  51. }
  1. Realml类 用于获取安全数据,给用户添加角色和权限,认证提交的用户是否合法,并通过用户获取安全数据

    package com.ztwow.springshiro.config;

    import com.ztwow.springshiro.entity.Permission;
    import com.ztwow.springshiro.entity.Role;
    import com.ztwow.springshiro.entity.User;
    import com.ztwow.springshiro.service.ILoginService;
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authc.SimpleAuthenticationInfo;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.authz.SimpleAuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    import org.springframework.beans.factory.annotation.Autowired;

    /**

    • 实现AuthorizingRealm接口用户用户认证
      *
    • AuthorizingRealm
    • 授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,
    • 常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限
    • */

      public class MyShiroRealm extends AuthorizingRealm {

      //用于用户查询
      @Autowired
      private ILoginService loginService;

      /**

      • 角色权限和对应权限添加
        *
      • */
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //获取登录用户名
        String name = (String) principalCollection.getPrimaryPrincipal();
        //查询用户名称
        User user = loginService.findByName(name);
        //添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        for(Role role:user.getRoles()) {

        1. //添加角色
        2. simpleAuthorizationInfo.addRole(role.getRoleName());
        3. for (Permission permission : role.getPermissions()) {
        4. //添加权限
        5. simpleAuthorizationInfo.addStringPermission(permission.getPermission());
        6. }

        }
        return simpleAuthorizationInfo;
        }

        /*

      • 用户认证
        *
      • */
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if(authenticationToken.getPrincipal() == null){

        1. return null;

        }

        String name = authenticationToken.getPrincipal().toString();
        User user = loginService.findByName(name);

        if(user == null){

        1. //用户不存在返回后会报出异常
        2. return null;

        }else{

        1. //这里验证authenticationToken和simpleAuthenticationInfo的信息
        2. SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name,user.getPassword().toString(),getName());
        3. return simpleAuthenticationInfo;

        }

        }
        }

8.Controller类

  1. package com.ztwow.springshiro.controller;
  2. import com.ztwow.springshiro.entity.Role;
  3. import com.ztwow.springshiro.entity.User;
  4. import com.ztwow.springshiro.service.ILoginService;
  5. import org.apache.shiro.SecurityUtils;
  6. import org.apache.shiro.authc.UsernamePasswordToken;
  7. import org.apache.shiro.authz.annotation.RequiresPermissions;
  8. import org.apache.shiro.authz.annotation.RequiresRoles;
  9. import org.apache.shiro.subject.Subject;
  10. import org.springframework.web.bind.annotation.RequestBody;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RequestMethod;
  13. import org.springframework.web.bind.annotation.RestController;
  14. import javax.annotation.Resource;
  15. import java.util.Map;
  16. @RestController
  17. public class LoginController {
  18. @Resource
  19. private ILoginService loginService;
  20. //退出的时候是get请求,主要是用于退出
  21. @RequestMapping(value = "/login",method = RequestMethod.GET)
  22. public String login(){
  23. return "login";
  24. }
  25. //post登录
  26. @RequestMapping(value = "/login",method = RequestMethod.POST)
  27. public String login(@RequestBody Map map){
  28. //添加用户认证信息
  29. Subject subject = SecurityUtils.getSubject();
  30. UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
  31. map.get("username").toString(),
  32. map.get("password").toString());
  33. //进行验证,这里可以捕获异常,然后返回对应信息
  34. subject.login(usernamePasswordToken);
  35. return "login";
  36. }
  37. @RequestMapping(value = "/index")
  38. public String index(){
  39. return "index";
  40. }
  41. //登出
  42. @RequestMapping(value = "/logout")
  43. public String logout(){
  44. return "logout";
  45. }
  46. //错误页面展示
  47. @RequestMapping(value = "/error",method = RequestMethod.POST)
  48. public String error(){
  49. return "error ok!";
  50. }
  51. //数据初始化
  52. @RequestMapping(value = "/addUser")
  53. public String addUser(@RequestBody Map<String,Object> map){
  54. User user = loginService.addUser(map);
  55. return "addUser is ok! \n" + user;
  56. }
  57. //角色初始化
  58. @RequestMapping(value = "/addRole")
  59. public String addRole(@RequestBody Map<String,Object> map){
  60. Role role = loginService.addRole(map);
  61. return "addRole is ok! \n" + role;
  62. }
  63. //注解的使用
  64. @RequiresRoles("admin")
  65. @RequiresPermissions("create")
  66. @RequestMapping(value = "/create")
  67. public String create(){
  68. return "Create success!";
  69. }
  70. }

主要流程:页面所有的操作请求都会通过subject(代表当前用户),然后将subject绑定到SecurityManager上,由SecurityManager管理有所与subject的交互,当SecurityManager需要验证用户身份是否合法,会通过Realm提供的Authentication和Authorization认证用户获取安全数据

发表评论

表情:
评论列表 (有 0 条评论,334人围观)

还没有评论,来说两句吧...

相关阅读