Apache shiro例子

apache shiro例子
闲来无事看到之前写的shiro例子,传上来,

之前在一家公司接触过一个项目用到了shiro,不过那个项目是公司买来的,前后端封装的比较厉害,用着不是并那么方便,简单学习shiro后,写了个小demo。
shiro相比spring的安全框架上手要友好的多。

这是基本结构。
在这里插入图片描述
我使用的是spring boot ,这样方便配置,简单的写了个登陆过程。采用spring的thymeleaf。spring data jpa读取数据库中用户信息作权限判断
启动类就不贴了,会spring boot的都没问题

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.1.4.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>org.zhengyj</groupId>
   <artifactId>springboot-shiro</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>springboot-shiro</name>
   <description>Demo project for Spring Boot</description>

   <properties>
       <java.version>1.8</java.version>
   </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-data-jpa</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-thymeleaf</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.47</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.6</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <optional>true</optional>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

</project>

application.yml
server:
  port: 8081
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot_shiro?useUnicode=true&amp;characterEncoding=UTF-8&useSSL=true
    username: root
    password: root123
    type: com.alibaba.druid.pool.DruidDataSource
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
  http:
    encoding:
      charset: utf-8
      enabled: true
  thymeleaf:
    prefix: classpath:/templates/
login.html
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
<form action="/loginsave">
    用户名:<input name="name" type="text"/><br>
    密码:<input name="password" type="text"/><br>
    <input type="submit" value="登录系统"/>
</form>
<p th:text="${hello}"></p>
</body>
</html>
controller
package org.zhengyj.springbootshiro.controller;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.zhengyj.springbootshiro.entity.User;
import org.zhengyj.springbootshiro.service.LoginService;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

/**
 *
 * @Author zhengyj
 * @Description :登录控制层
 * @Date 2019/4/17
 **/

@Controller
public class LoginController {


    /**
     * 首页
     * @return
     */
    @RequestMapping(value = "/index")
    public String index(){
        return "index";
    }
    /**
     * 登录
     * @return
     */
    @RequestMapping(value = "/login")
    public String login(){
        return "login";
    }
	/**
	* 此处做权限跳转处理,返回不同页面
	*/
    @RequestMapping(value = "/loginsave")
    public String loginSave(User user){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(user.getName(),user.getPassword());
        try{
            subject.login(token);
            //这个index页面就是随便写点什么标注下就行
            return "index";
        }catch(UnknownAccountException e){
            return "login";
        }catch(IncorrectCredentialsException i){
            return "login";
        }
    }

}
User类(这个可以用lombok,有点懒了)
package org.zhengyj.springbootshiro.entity;
import javax.persistence.*;
import java.util.List;

/**
     *
     * @Author zhengyingjun
     * @Description :shiro 用户类
     * @Date 2019/4/17
     **/
    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;

        @Column(unique = true)
        private String name;

        private String password;
        @OneToMany(cascade = CascadeType.ALL,mappedBy = "user")
        private List<Role> roles;

        public List<Role> getRoles() {
            return roles;
        }

        public void setRoles(List<Role> roles) {
            this.roles = roles;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }
}

Role
package org.zhengyj.springbootshiro.entity;

import javax.persistence.*;
import java.util.List;

/**
 *
 * @Author zhengyingjun
 * @Description :shiro 角色类
 * @Date 2019/4/17
 **/

@Entity
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

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

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<Permission> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<Permission> permissions) {
        this.permissions = permissions;
    }

    @OneToMany(cascade = CascadeType.ALL,mappedBy = "role")
    private List<Permission> permissions;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
}
Permission
package org.zhengyj.springbootshiro.entity;

import javax.persistence.*;

/**
 *
 * @Author zhengyingjun
 * @Description : shiro 权限类
 * @Date 2019/4/17
 **/
@Entity
public class Permission {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String permission;

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

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPermission() {
        return permission;
    }

    public void setPermission(String permission) {
        this.permission = permission;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}
RoleRepository(使用的Spring Data JPA)
package org.zhengyj.springbootshiro.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.zhengyj.springbootshiro.entity.Role;
/**
 *
 * @Author zhengyingjun
 * @Description :角色
 * @Date 2019/4/17
 **/

public interface RoleRepository extends JpaRepository<Role,Long> {
}
UserRepository
package org.zhengyj.springbootshiro.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.zhengyj.springbootshiro.entity.User;
/**
 *
 * @Author zhengyingjun
 * @Description :用户
 * @Date 2019/4/17
 **/
public interface UserRepository extends JpaRepository<User,Long> {
    /**
     *自定义查询
     * @param name
     * @return
     */
    User findByName(String name);
}
service接口(有些好像是没用上)
package org.zhengyj.springbootshiro.service;
import org.zhengyj.springbootshiro.entity.Role;
import org.zhengyj.springbootshiro.entity.User;
/**
 *
 * @Author zhengyingjun
 * @Description :业务
 * @Date 2019/4/17
 **/

public interface LoginService {

    User addUser(User user);

    Role addRole(User user,String rolename);

    User findByName(String name);
}
service实现类
package org.zhengyj.springbootshiro.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zhengyj.springbootshiro.entity.Permission;
import org.zhengyj.springbootshiro.entity.Role;
import org.zhengyj.springbootshiro.entity.User;
import org.zhengyj.springbootshiro.repository.RoleRepository;
import org.zhengyj.springbootshiro.repository.UserRepository;
import org.zhengyj.springbootshiro.service.LoginService;
import java.util.ArrayList;
import java.util.List;
/**
 *
 * @Author zhengyingjun
 * @Description :具体实现
 * @Date 2019/4/17
 **/

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Override
    public User addUser(User user) {
        return userRepository.save(user);
    }

    @Override
    public Role addRole(User user,String rolename) {
        Role role = new Role();
        role.setRoleName(rolename);
        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> list = new ArrayList<>();
        list.add(permission1);
        list.add(permission2);
        //放入role统一保存
        role.setPermissions(list);
        roleRepository.save(role);
        return role;
    }
    @Override
    public User findByName(String name) {
        return userRepository.findByName(name);
    }
}

接下来就是最重要的配置了
这个简要说明下,用到哪个页面就配置哪个

package org.zhengyj.springbootshiro.config;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * @Author zhengyingjun
 * @Description :shiro 过滤配置
 * @Date 2019/4/17
 **/
@Configuration
public class ShiroConfiguration {
    /**
     * 加入注解
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name = "myShiroRealm")
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }

    /**
     * 权限管理
     * @return
     */
    @Bean(name = "defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        Map<String,String> map = new HashMap<>();
        //登录
        shiroFilterFactoryBean.setLoginUrl("/login");
        //首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
        //报错页
        shiroFilterFactoryBean.setUnauthorizedUrl("/error");
        //退出
        map.put("/logout","logout");
        map.put("/login","anon");
        map.put("/loginsave","anon");
        //对所有用户认证
        map.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }
}

认证与校验

package org.zhengyj.springbootshiro.config;
import lombok.extern.slf4j.Slf4j;
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;
import org.zhengyj.springbootshiro.entity.Permission;
import org.zhengyj.springbootshiro.entity.Role;
import org.zhengyj.springbootshiro.entity.User;
import org.zhengyj.springbootshiro.service.LoginService;

@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private LoginService service;
    /**
     * 添加权限
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("授权");
        User user = (User) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Role role : user.getRoles()) {
            //添加角色
            simpleAuthorizationInfo.addRole(role.getRoleName());
            //添加权限
            for (Permission permission : role.getPermissions()) {
                simpleAuthorizationInfo.addStringPermission(permission.getPermission());
            }
        }
        return simpleAuthorizationInfo;
    }

    /**
     * 认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("认证");
        //??先进行认证?
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
       String name = (String)authenticationToken.getPrincipal();
        User user = service.findByName(name);
        //空值校验
        if (user == null) {
            return null;
        } else {
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getName(), user.getPassword(), getName());
            return simpleAuthenticationInfo;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值