shiro的简单使用

作者: Anur | 来源:发表于2017-09-06 21:48 被阅读109次

    一、shiro认证

    1、请求认证
    Subject subject = SecurityUtils.getSubject();// 根据运行环境返回subject
    subject.login(token);// 这里的token一般指的是 UsernamePasswordToken,参数有
                         // String username, String password, boolean rememberMe, String host ,有多种构造函数
    
    2、通过SecurityManager执行认证
    public void login(AuthenticationToken token) throws AuthenticationException {
        this.clearRunAsIdentitiesInternal();
        Subject subject = this.securityManager.login(this, token);// 调用securityManager
        String host = null;
        PrincipalCollection principals;
        if (subject instanceof DelegatingSubject) {
            DelegatingSubject delegating = (DelegatingSubject)subject;
            principals = delegating.principals;
            host = delegating.host;
        } else {
            principals = subject.getPrincipals();
        }// 无论怎么样principals = subject.getPrincipals();既用户名
    
        if (principals != null && !principals.isEmpty()) {
            this.principals = principals;
            this.authenticated = true;
            if (token instanceof HostAuthenticationToken) {
                host = ((HostAuthenticationToken)token).getHost();
            }
    
            if (host != null) {
                this.host = host;
            }
    
            Session session = subject.getSession(false);
            if (session != null) {
                this.session = this.decorate(session);
            } else {
                this.session = null;
            }
    
        } else {
            String msg = "Principals returned from securityManager.login( token ) returned a null or empty value.  This value must be non null and populated with one or more elements.";
            throw new IllegalStateException(msg);
        }
    }
    
    3、SecurityManager通过ModularRealmAuthenticator再通过realm进行认证

    在自定义的Realm中完成认证

    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取用户的输入的账号.
        String username = (String) token.getPrincipal();
        User user = userService.selectByUsername(username);
        String password = user.getPassword();
        if (user == null) throw new UnknownAccountException();
        if (0 == user.getEnable()) {
            throw new LockedAccountException(); // 帐号锁定
        }
    
        //通过这个进行认证,并返回
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, null, getName());
    
        Session session = SecurityUtils.getSubject().getSession();// 当验证都通过后,把用户信息放在session里
        session.setAttribute("userSession", user);
        session.setAttribute("userSessionId", user.getId());
        return simpleAuthenticationInfo;
    }
    
    4、认证的配置

    这些配置在shiro的配置文件中完成

        @Bean
        public MyShiroRealm myShiroRealm() {
            MyShiroRealm myShiroRealm = new MyShiroRealm();
            myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());// 凭证验证器
            return myShiroRealm;
        }
    
        @Bean
        public HashedCredentialsMatcher hashedCredentialsMatcher() {// 凭证验证器
            HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    
            hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
            hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
    
            return hashedCredentialsMatcher;
        }
    

    二、shiro授权

    1、ModularRealmAuthenticator通过realm进行认证

    在自定义的Realm中完成授权,将用户的权限查出,配置到info中去。

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    
        String username = (String) principalCollection.getPrimaryPrincipal();
        User user = userService.selectByUsername(username);
    
        Map<String, Object> map = new HashMap();
        map.put("userid", user.getId());
    
        List<Resources> resourcesList = resourcesService.loadUserResources(map);
    
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();  // 权限信息对象info
        for (Resources resources : resourcesList) {
            info.addStringPermission(resources.getResurl()); // 在这里存放查出的用户的所有的角色(role)及权限(permission)
        }
        return info;
    }
    
    2、授权的配置,通过filterChainDefinitionMap在Shiro的拦截器中配置

    这些配置在shiro的配置文件中完成

       @Bean
        public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
            ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            shiroFilterFactoryBean.setSuccessUrl("/usersPage");// 登录成功跳转的页
            shiroFilterFactoryBean.setUnauthorizedUrl("/403");// 未授权界面;
    
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
            filterChainDefinitionMap.put("/logout", "logout");// 配置登出地址,不需要专门去写控制器
            filterChainDefinitionMap.put("/css/**", "anon");
            filterChainDefinitionMap.put("/js/**", "anon");
            filterChainDefinitionMap.put("/img/**", "anon");
            filterChainDefinitionMap.put("/font-awesome/**", "anon");// 首先放过一般的静态资源
      
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); // 配置所有需要拦截的地址
            return shiroFilterFactoryBean;
        }
    
    2.1配置规则
    // 将需要配置的地址放入map中,规则如下:
    /**
    anon:例子/admins/**=anon 没有参数,表示可以匿名使用。
    
    authc:例如/admins/user/**=authc表示需要认证(登录)才能使用,没有参数
    
    roles(角色):例子/admins/user/**=roles[admin],参数可以写多个,多个时必须加上引号,
    并且参数之间用逗号分割,当有多个参数时,例如admins/user/**=roles["admin,guest"],
    每个参数通过才算通过,相当于hasAllRoles()方法。
    
    perms(权限):例子/admins/user/**=perms[user:add:*],参数可以写多个,多个时必须加上引号,
    并且参数之间用逗号分割,例如/admins/user/**=perms["user:add:*,user:modify:*"],
    当有多个参数时必须每个参数都通过才通过,想当于isPermitedAll()方法。
    
    rest:例子/admins/user/**=rest[user],根据请求的方法,相当于/admins/user/**=perms[user:method] ,
    其中method为post,get,delete等。
    
    port:例子/admins/user/**=port[8081],当请求的url的端口不是8081是跳转到
    schemal://serverName:8081?queryString,其中schmal是协议http或https等,
    serverName是你访问的host,8081是url配置里port的端口,queryString是你访问的url里的?后面的参数。
    
    authcBasic:例如/admins/user/**=authcBasic没有参数表示httpBasic认证
    
    ssl:例子/admins/user/**=ssl没有参数,表示安全的url请求,协议为https
    
    user:例如/admins/user/**=user没有参数表示必须存在用户,当登入操作时不做检查
    */
    // 详情参考shiro.web.filter源码
    

    三、shiro认证

    在shiro的配置文件中加入

    @Bean
        public ShiroDialect shiroDialect() {
            return new ShiroDialect();
        }
    

    html中加入xmlns

    <html lang="zh_CN" xmlns:th="http://www.thymeleaf.org"
          xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
    

    maven依赖

    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>1.2.1</version> 
    </dependency>
    

    相关文章

      网友评论

        本文标题:shiro的简单使用

        本文链接:https://www.haomeiwen.com/subject/vbovjxtx.html