spring boot与shiro的简单使用

一、spring boot与shiro的使用,实现登录操作,项目结构图如图所示:
这里写图片描述
二、pom.xml依赖配置:

  <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.6.RELEASE</version>
  </parent>

  <dependencies>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-autoconfigure</artifactId>
      </dependency>
      <!-- spring boot 中web socket服务依赖 -->
      <dependency>  
          <groupId>org.springframework.boot</groupId>  
          <artifactId>spring-boot-starter-websocket</artifactId>  
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-Java</artifactId>
          <version>5.1.44</version>
      </dependency>
      <dependency>
          <groupId>org.apache.shiro</groupId>
          <artifactId>shiro-spring</artifactId>
          <version>1.3.2</version>
      </dependency>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.4</version>
      </dependency>
      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <scope>provided</scope>
      </dependency>
      <!-- log4j依赖 -->
      <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
      </dependency>
  </dependencies>

三、数据库表结构

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(16) NOT NULL,
  `user_password` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
);
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(32) NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);
CREATE TABLE `permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `permission` varchar(32) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

四、shiro的过滤配置,使用@Configuration注解;

/**
 * @ClassName: MonitorShiroConfiguration.java
 * @Description: 过滤配置;
 * @author wangmin
 * @date 2018年6月4日-下午5:11:54
 * @version 1.0V
 */
@Configuration
public class MonitorShiroConfiguration {

    /**
     * 将自定义的验证方式加入到容器中;
     * @return
     * @date 2018年6月4日-下午5:13:53
     * @author wangmin
     */
    @Bean
    public MonitorShiroRealm monitorShiroRealm () {
        return new MonitorShiroRealm();
    }

    /**
     * 权限管理,配置主要是Realm的管理认证;
     * @return
     * @date 2018年6月4日-下午5:20:53
     * @author wangmin
     */
    @Bean
    public org.apache.shiro.mgt.SecurityManager securityManager () {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(monitorShiroRealm());
        return securityManager;
    }

    /**
     * Filter工厂,设置对应的过滤条件和跳转条件;
     * @param securityManager
     * @return
     * @date 2018年6月4日-下午5:23:52
     * @author wangmin
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean (org.apache.shiro.mgt.SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String, String> map = new HashMap<String, String>();
        //  登出
        map.put("/logout","logout");
        //  对所有用户认证
        map.put("/**","authc");
        //  配置不会被拦截的链接
        map.put("/web", "anon");
        //  登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //  首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //  错误页面,认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    /**
     * 加入注解的使用,不加入这个注解不生效;
     * @param securityManager
     * @return
     * @date 2018年6月4日-下午5:28:21
     * @author wangmin
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}

五、配置过滤条件及验证,继承AuthorizingRealm接口用户用户认证;

/**
 * @ClassName: MonitorShiroRealm.java
 * @Description: 配置过滤条件及验证,继承AuthorizingRealm接口用户用户认证;
 * @author wangmin
 * @date 2018年6月4日-下午4:48:37
 * @version 1.0V
 */
public class MonitorShiroRealm extends AuthorizingRealm {

    @Autowired
    private ILoginService loginService;

    /**
     * 角色权限和对应权限添加;
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //  获取登录用户名
        String userName = String.valueOf(principalCollection.getPrimaryPrincipal());
        User user = loginService.findByName(userName);

        //  添加角色和权限
        SimpleAuthorizationInfo author = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //  添加角色
            author.addRole(role.getRoleName());
            for (Permission permission : role.getPermissions()) {
                //  添加权限
                author.addStringPermission(permission.getPermission());
            }
        }

        return author;
    }

    /**
     * 用户验证;
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        /**在进行post请求时,会先验证,然后再到请求*/
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //  获取用户信息
        String userName = String.valueOf(authenticationToken.getPrincipal());

        User user = loginService.findByName(userName);
        if (user == null) {
            return null;
        } else {
            //  验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userName, user.getPassword(), getName());
            return authenticationInfo;
        }
    }

}

六、实体类

/**
 * @ClassName: User.java
 * @Description: 用户实体类;
 * @author wangmin
 * @date 2018年6月4日-下午4:25:20
 * @version 1.0V
 */
@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "user_password")
    private String password;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private List<Role> roles;
}
/***********************************************************************************/
/**
 * @ClassName: Role.java
 * @Description: 角色实体类,只考虑一个用户有多个角色,不考虑多对多的关系;
 * @author wangmin
 * @date 2018年6月4日-下午4:27:33
 * @version 1.0V
 */
@Entity
@Data
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "role_name")
    private String roleName;

    @ManyToOne(fetch = FetchType.EAGER)
    private User user;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "role")
    private List<Permission> permissions;
}
/***********************************************************************************/
/**
 * @ClassName: Permission.java
 * @Description: 用户权限;
 * @author wangmin
 * @date 2018年6月4日-下午4:42:03
 * @version 1.0V
 */

@Entity
@Data
public class Permission {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String permission;

    @ManyToOne(fetch = FetchType.EAGER)
    private Role role;
}

七、dao(Repository)层操作:

@NoRepositoryBean
public interface BaseRepository <T, I extends Serializable> extends PagingAndSortingRepository<T, I>, JpaSpecificationExecutor<T> {
}
/***********************************************************************************/
/**
 * @ClassName: UserRepository.java
 * @Description: "Invalid derived query! No property name found for type User!"出现这个错误是因为实体类中没有
 * 某个属性(No property 属性名 found for type 类名);
 * @author wangmin
 * @date 2018年6月5日-上午9:06:54
 * @version 1.0V
 */
public interface UserRepository extends BaseRepository<User, Long>{

    User findByUserName (String name);
}
/***********************************************************************************/
public interface RoleRepository extends BaseRepository<Role, Long>{

}

八、service层

/**
 * @ClassName: ILoginService.java
 * @Description: 登录操作service接口类;
 * @author wangmin
 * @date 2018年6月4日-下午4:59:04
 * @version 1.0V
 */
public interface ILoginService {

    /**
     * 根据用户名获取用户信息;
     * @param userName
     * @return
     * @date 2018年6月4日-下午4:58:27
     * @author wangmin
     */
    User findByName (String userName);

    /**
     * 添加用户信息;
     * @param map
     * @return
     * @date 2018年6月4日-下午5:45:34
     * @author wangmin
     */
    User addUser(Map<String, Object> map);

    /**
     * 添加用户角色;
     * @param map
     * @return
     * @date 2018年6月4日-下午5:47:30
     * @author wangmin
     */
    Role addRole(Map<String, Object> map);
}
/***********************************************************************************/
/**
 * @ClassName: LoginServiceImpl.java
 * @Description: 登录操作service接口实现类;
 * @author wangmin
 * @date 2018年6月4日-下午4:59:29
 * @version 1.0V
 */
@Service(value="loginServiceImpl")
public class LoginServiceImpl implements ILoginService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    /**
     * 添加用户信息;
     */
    @Override
    public User addUser(Map<String, Object> map) {
        User user = new User();
        user.setUserName(String.valueOf(map.get("userName")));
        user.setPassword(String.valueOf(map.get("password")));
        userRepository.save(user);
        return user;
    }

    /**
     * 添加角色信息;
     */
    @Override
    public Role addRole(Map<String, Object> map) {
        User user = userRepository.findOne(Long.valueOf(map.get("userId").toString()));
        Role role = new Role();
        role.setRoleName(map.get("roleName").toString());
        role.setUser(user);
        Permission permission1 = new Permission();
        permission1.setPermission("create");
        permission1.setRole(role);
        Permission permission2 = new Permission();
        permission2.setPermission("update");
        permission2.setRole(role);
        List<Permission> permissions = new ArrayList<Permission>();
        permissions.add(permission1);
        permissions.add(permission2);
        role.setPermissions(permissions);
        roleRepository.save(role);
        return role;
    }

    /**
     * 根据用户名获取用户信息;
     */
    @Override
    public User findByName(String userName) {
        return userRepository.findByUserName(userName);
    }
}

九、controller层

/**
 * @ClassName: LoginController.java
 * @Description: 用户登录controller;
 * @author wangmin
 * @date 2018年6月4日-下午5:29:34
 * @version 1.0V
 */
@RestController
public class LoginController {

    @Resource(name = "loginServiceImpl")
    private ILoginService loginService;

    /**
     * 退出的时候是get请求,主要是用于退出;
     * @return
     * @date 2018年6月4日-下午5:55:25
     * @author wangmin
     */
    @RequestMapping(value = "/login",method = RequestMethod.GET)
    public String login(){
        return "login";
    }

    /**
     * post登录;
     * @param map
     * @return
     * @date 2018年6月4日-下午5:55:10
     * @author wangmin
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public String login(@RequestBody Map<String, String> map){
        //  添加用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                String.valueOf(map.get("username")),
                String.valueOf(map.get("password")));
        //  进行验证,这里可以捕获异常,然后返回对应信息
        subject.login(usernamePasswordToken);
        return "login";
    }

    /**
     * 首页;
     * @return
     * @date 2018年6月4日-下午5:55:01
     * @author wangmin
     */
    @RequestMapping(value = "/index")
    public String index(){
        return "index";
    }

    /**
     * 登出;
     * @return
     * @date 2018年6月4日-下午5:54:38
     * @author wangmin
     */
    @RequestMapping(value = "/logout")
    public String logout(){
        return "logout";
    }

    /**
     * 错误页面展示;
     * @return
     * @date 2018年6月4日-下午5:54:19
     * @author wangmin
     */
    @RequestMapping(value = "/error",method = RequestMethod.POST)
    public String error(){
        return "error ok!";
    }

    /**
     * 数据初始化;
     * @param map
     * @return
     * @date 2018年6月4日-下午5:54:02
     * @author wangmin
     */
    @RequestMapping(value = "/addUser")
    public String addUser(@RequestBody Map<String,Object> map){
        User user = loginService.addUser(map);
        return "addUser is ok! \n" + user;
    }

    /**
     * 角色初始化;
     * @param map
     * @return
     * @date 2018年6月4日-下午5:53:48
     * @author wangmin
     */
    @RequestMapping(value = "/addRole")
    public String addRole(@RequestBody Map<String,Object> map){
        Role role = loginService.addRole(map);
        return "addRole is ok! \n" + role;
    }


    /**
     * 注解的使用
     * @return
     * @date 2018年6月4日-下午5:53:33
     * @author wangmin
     */
    @RequiresRoles("admin")
    @RequiresPermissions("create")
    @RequestMapping(value = "/create")
    public String create(){
        return "Create success!";
    }
}

猜你喜欢

转载自blog.csdn.net/wm_zq/article/details/80591965