springboot—— Shiro实现认证和授权功能

一、数据库模板设计

在本文中,我们使用RBAC(Role-Based Access Control,基于角色的访问控制)模型设计用户,角色和权限间的关系。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。这样,就构造成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系

一个用户对应一个或者多个角色。
一个角色对应一个或者多个权限。
一个权限对应能够访问对应的API或url资源。

 

1 . RBAC基本实体关系,Permission类(权限资源) :


/**
 * Created by EalenXie on 2019/3/25 11:15.
 * <p>
 * 权限许可(Permission) 操作 及其能访问url 权限对应一个url地址
 */
@Entity
@Table(name = "system_shiro_permission")
public class Permission extends BaseEntity {
    @Column(unique = true)
    private String name;                //权限名 唯一
    @Column(unique = true)
    private String url;                 //访问地址信息 唯一
    private String description;         //描述信息
    //省略getter/setter
}

 

2 . Role类(用户角色),一个角色拥有一个或者多个权限 :


/**
 * Created by EalenXie on 2019/3/25 11:18.
 * <p>
 * 角色(Role) 角色下面对应多个权限
 */
@Entity
@Table(name = "system_shiro_role")
public class Role extends BaseEntity {

    @Column(unique = true)
    private String name;                    //角色名 唯一
    private String description;             //描述信息
    @ManyToMany(fetch= FetchType.EAGER)
    private List<Permission> permissions;   //一个用户角色对应多个权限
    //省略getter/setter
}

 

3 . User类(用户),一个用户拥有一个或者多个角色 :


/**
 * Created by EalenXie on 2019/3/25 11:01.
 * <p>
 * 用户表(User) 用户下面对应多个角色
 */
@Entity
@Table(name = "system_shiro_user")
public class User extends BaseEntity {
    @Column(unique = true)
    private String username;//用户名 唯一
    private String password;//用户密码
    private String passwordSalt;//用户密码加密盐值
    @ManyToMany(fetch = FetchType.EAGER)
    private List<Role> roles;//用户角色  一个用户可能有一个角色,也可能有 多个角色
    //省略getter/setter
}

以上是对应关系的实体,数据库字段根据上述实体创建,这里就不写出来了。设计到的查询根据实际情况自己写,这里主要是讲shiro

二:Shiro整合实现思路

我们先来屡一下思路,实现认证权限功能主要可以归纳为3点:

1.定义一个ShiroConfig配置类,配置 SecurityManager Bean , SecurityManager为Shiro的安全管理器,管理着所有Subject;

2.在ShiroConfig中配置 ShiroFilterFactoryBean ,它是Shiro过滤器工厂类,依赖SecurityManager ;

3.自定义Realm实现类,包含 doGetAuthorizationInfo()doGetAuthenticationInfo()方法 

下面我们就来实现这些步骤:

 1、定义ShiroConfig配置类

/**
 * Shiro配置
 */
@Configuration
public class ShiroConfig {
    @Resource
    private OAuth3Realm userAuthRealm;
    /**
     * 配置安全管理器
     * @param oAuth3Realm UserRealm
     * @return DefaultWebSecurityManager
     */
    @Bean
    public SecurityManager securityManager(OAuth3Realm oAuth3Realm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(oAuth3Realm);
        return securityManager;
    }

    /**
     * 配置Shiro过滤器工厂
     * 配置 资源访问策略 . web应用程序 shiro核心过滤器配置
     */
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, UrlConfig urlConfig) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 注册安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 定义资源访问规则
        Map<String, String> filterMap = new LinkedHashMap<String, String>(16);
        /*
         * 过滤器说明
         * anon:不需要认证就可以访问的资源
         * authc:需要登录认证才能访问的资源
         * perms:需要指定权限才能访问的资源
         */
        // 需要登录认证才能访问的资源
        //oauth过滤,anon:不需要认证就可以访问的资源
        Map<String, Filter> filters = new LinkedHashMap<>();
        filters.put("oauth3", new OAuth3Filter());
        // TODO 增加新的B端用户拦截器
        shiroFilterFactoryBean.setFilters(filters);
        //排除配置
        if (urlConfig.getAnonUrl() != null && !urlConfig.getAnonUrl().isEmpty()) {
            for (String anonUrl : urlConfig.getAnonUrl()) {
                filterMap.put(anonUrl, "anon");
            }
        }
        //对所有用户认证 对B端访问路由进行拦截
        filterMap.put("/**", "oauth3");

        //配置 拦截过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        return shiroFilterFactoryBean;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 开启shiro 注解支持. 使以下注解能够生效 :
     * 需要认证 {@link org.apache.shiro.authz.annotation.RequiresAuthentication RequiresAuthentication}
     * 需要用户 {@link org.apache.shiro.authz.annotation.RequiresUser RequiresUser}
     * 需要访客 {@link org.apache.shiro.authz.annotation.RequiresGuest RequiresGuest}
     * 需要角色 {@link org.apache.shiro.authz.annotation.RequiresRoles RequiresRoles}
     * 需要权限 {@link org.apache.shiro.authz.annotation.RequiresPermissions RequiresPermissions}
     * 启用shiro注解
     *加入注解的使用,不加入这个注解不生效
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(secu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值