【Shiro】一步步的看Shiro (一)

2021-07-06  本文已影响0人  程序员佩奇

初始化一下环境

<?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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.shiro.tutorials</groupId>
    <artifactId>shiro-tutorial</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>First Apache Shiro Application</name>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        <!-- 运行main函数java代码用的,如果用idea可以不考虑 -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <classpathScope>test</classpathScope>
                    <mainClass>Tutorial</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.4.1</version>
        </dependency>
        <!-- slf4j日志包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
            <scope>test</scope>
        </dependency>
       <!-- 桥接包来代替commons-logging把具体实现委托给slf4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.21</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tutorial {
    private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
    public static void main(String[] args) {
        log.info("My First Apache Shiro Application");
        System.exit(0);
    }
}

上面只是搭建一个很简单的应用,下面就具体说说需要配置写什么

SecurityManager

Configuration

src/main/resources/shiro.ini

# =============================================================================
# Tutorial INI configuration
#
# Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)
# =============================================================================
# -----------------------------------------------------------------------------
# [users] 用来配置用户以及密码角色的,后面可以通过数据库来配置,这里只是演示
# 配置方法:username = password, role1, role2, ..., roleN
# -----------------------------------------------------------------------------
[users]
root = secret, admin
guest = guest, guest
presidentskroob = 12345, president
darkhelmet = ludicrousspeed, darklord, schwartz
lonestarr = vespa, goodguy, schwartz
# -----------------------------------------------------------------------------
# roles是配置角色的
# 配置方法:roleName = perm1, perm2, ..., permN
# -----------------------------------------------------------------------------
[roles]
admin = *
schwartz = lightsaber:*
goodguy = winnebago:drive:eagle5
public static void main(String[] args) {
    log.info("My First Apache Shiro Application");
    //1.IniSecurityManagerFactory通过工厂模式的方法读取classpath路径下的shiro.ini文件,得到一个工厂,
    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
    //2.通过工厂获取到SecurityManager的实例对象
    SecurityManager securityManager = factory.getInstance();
    //3.这里是设置到SecurityUtils的静态单利当中,JVM可以直接访问,如果说使用spring或者其他复杂的应用,会通过框架的方式放在特定的内存中进行维护(例如在Web应用程序的ServletContext或Spring)
    SecurityUtils.setSecurityManager(securityManager);
    System.exit(0);
}

Subject

Subject currentUser = SecurityUtils.getSubject();
//我们可以通过SecurityUtils.getSubject()的方式获取当前用户,当用户还没有登陆的时候则是微登陆状态匿名的,官方解释;当前执行用户的安全特定视图,它基于与当前线程或传入请求相关联的用户数据获取对象。

那么我们有了上面的用户主题,可以用来做些什么呢?看下面。

session

if ( !currentUser.isAuthenticated() ) {
    //我们用GUI特定的方式收集principals(主体,用户) and credentials(凭据,密码)
    //比如form表单提交的用户名密码,或者OpenId等
    //这里使用的是用户名密码
    UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
    //内置的,设置登陆后记住我
    token.setRememberMe(true);
    currentUser.login(token);
}
try {
    currentUser.login( token );
    //正常登陆
} catch ( UnknownAccountException uae ) {
    //用户不存在的异常
} catch ( IncorrectCredentialsException ice ) {
    //密码不匹配,是否在进行重试呢?
} catch ( LockedAccountException lae ) {
    //用户被锁定了,是不是需要给告知用户被锁定呢?
}
    ... more types exceptions to check if you want ...
} catch ( AuthenticationException ae ) {
    //意外情况
}
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Tutorial {
    private static final transient Logger log = LoggerFactory.getLogger(Tutorial.class);
    public static void main(String[] args) {
        log.info("My First Apache Shiro Application");
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
        // 获取当前用户,在没登陆的情况下是匿名的
        Subject currentUser = SecurityUtils.getSubject();
        // 获取shiro的session实例
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");
        if (value.equals("aValue")) {
            log.info("Retrieved the correct value! [" + value + "]");
        }
        // 校验是否认证过了
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
            token.setRememberMe(true);
            try {
                currentUser.login(token);
            } catch (UnknownAccountException uae) {
                log.info("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            }
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) {
                //unexpected condition?  error?
            }
        }
        //获取当前登录用户信息
        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
        //校验角色
        if (currentUser.hasRole("schwartz")) {
            log.info("May the Schwartz be with you!");
        } else {
            log.info("Hello, mere mortal.");
        }
        //校验权限
        if (currentUser.isPermitted("lightsaber:wield")) {
            log.info("You may use a lightsaber ring.  Use it wisely.");
        } else {
            log.info("Sorry, lightsaber rings are for schwartz masters only.");
        }
        //还可以校验具体的某个功能的权限
        if (currentUser.isPermitted("winnebago:drive:eagle5")) {
            log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                    "Here are the keys - have fun!");
        } else {
            log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
        }
        //退出登陆
        currentUser.logout();
        System.exit(0);
    }
}

总结

上一篇 下一篇

猜你喜欢

热点阅读