• Shiro can be applied to any application

  • For a simple example, let’s run Shiro

  • This instance requires jdk1.6 or later and maven 2.2.1 or later

Let’s initialize the environment

  • pom.xml






    <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 - the 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>



        <! Java.main.main.main.main.main.main.main.main.main.main.main.main.main.main.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 log package -->



        <dependency>



            <groupId>org.slf4j</groupId>



            <artifactId>slf4j-simple</artifactId>



            <version>1.7.21</version>



            <scope>test</scope>



        </dependency>



       <! -- Bridge packages instead of commons-logging to delegate the implementation to SLf4J -->



        <dependency>



            <groupId>org.slf4j</groupId>



            <artifactId>jcl-over-slf4j</artifactId>



            <version>1.7.21</version>



            <scope>test</scope>



        </dependency>



    </dependencies>



</project>



Copy the code
  • To create a startup class insrc/main/java/Tutorial.java


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);



    }



}



Copy the code
  • Just do the main method

The above is just to build a very simple application, the following details need to configure what

SecurityManager

  • Shiro’s core manager. Almost everything in Shiro has to do with SecurityManager. There must be a SecurityManager in every Shiro application, so one thing we have to do is set up SecurityManager

Configuration

  • We can invoke SecurityManager, and Shiro provides a number of configuration items for us to start SecurityManager. Take a look

  • Shro.ini for example:

src/main/resources/shiro.ini



# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =



# Tutorial INI configuration



#



# Usernames/passwords are based on the classic Mel Brooks' film "Spaceballs" :)



# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --



# [users] is used to configure users and password roles



Username = password, role1, role2... , roleN



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --



[users]



root = secret, admin



guest = guest, guest



presidentskroob = 12345, president



darkhelmet = ludicrousspeed, darklord, schwartz



lonestarr = vespa, goodguy, schwartz



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --



Roles is configured for roles



RoleName = perm1, perm2... , permN



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --



[roles]



admin = *



schwartz = lightsaber:*



goodguy = winnebago:drive:eagle5



Copy the code
  • Once configured, we can instantiate the SecurityManager


public static void main(String[] args) {



    log.info("My First Apache Shiro Application");



    / / 1. IniSecurityManagerFactory reads the classpath directory path by using the method of the factory pattern shiro. Ini file, get a factory,



    Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");



    //2. Obtain the instance object of SecurityManager from the factory



    SecurityManager securityManager = factory.getInstance();



    //3. This is a static singleton set to SecurityUtils, which can be accessed directly by the JVM. If using Spring or other complex applications, it will be maintained in a specific memory by the framework (e.g. in the Web application ServletContext or Spring)! [](https://img.soogif.com/IhBHYjkYnJ9NtV2ZrAc4i1G5vYoBo4XU.gif?imageMogr2/thumbnail/! 51.79834606517432 p&scope = mdnice)



    SecurityUtils.setSecurityManager(securityManager);



    System.exit(0);



}



Copy the code

Subject

  • In the example above, we might need to know who is the user? What is the current user? Is the current user allowed to perform the XXX operation? , hence the concept of Subject

  • Why use Subject? Without User? Officially, User stands for human, but in an application, Subject can be described as a person, a third party process, a daemon account or something like that



Subject currentUser = SecurityUtils.getSubject();



Copy the code

We can obtain the current user through securityutils.getSubject (). When the user has not logged in, the micro-login status is anonymous, and the official explanation is given. Security-specific view of the currently executing user, which retrieves objects based on user data associated with the current thread or incoming request.

So what can we do with the user theme above? See below.

session

  • Session is a special instance maintained by Shiro, which can be thought of as an HttpSession. Shiro’s session has the added bonus of being independent of the HTTP environment

  • Httpsession-based in web environments, but sessions can also be used in non-Web environments

Having said Subject and session, how do we verify that the current user can perform an action? How to check their permissions, roles?

First we need to verify permissions for users we know are currently logged in. We all know that Subject represents the current user, but who? Is it the current user? Well, they’re anonymous until they’ve logged in once, and we can get the current logged in user.



if ( !currentUser.isAuthenticated() ) {



    // We collect the principals and credentials in guI-specific ways



    // For example, the username and password of the form submission, or OpenId, etc



    // The user name and password are used



    UsernamePasswordToken token = new UsernamePasswordToken("lonestarr"."vespa");



    // Built-in, set to remember me after login



    token.setRememberMe(true);



    currentUser.login(token);



}



Copy the code
  • In fact, the above is a login operation, so login encountered error how to do?


try {



    currentUser.login( token );



    // Normal login



catch ( UnknownAccountException uae ) {



    // The user does not exist



catch ( IncorrectCredentialsException ice ) {



    // The password does not match.



catch ( LockedAccountException lae ) {



    // The user is locked. Do you need to be told that the user is locked?



}



. more types exceptions to checkif you want ...



catch ( AuthenticationException ae ) {



    // Unexpected situation



}



Copy the code
  • You can also throw your own custom exception if shiro does not satisfy you

  • Ok, so what can we do once we have a logged in user?

  • Here’s an official example of how to do it:



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);



        // Get the current user, which is anonymous if not logged in



        Subject currentUser = SecurityUtils.getSubject();



        // Get shiro's session instance



        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 + "]");



        }



        // Verify whether the authentication is performed



        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?



            }



        }



        // Obtain information about the current login user



        log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");



        // Verify the role



        if (currentUser.hasRole("schwartz")) {



            log.info("May the Schwartz be with you!");



        } else {



            log.info("Hello, mere mortal.");



        }



        // Verify permissions



        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.");



        }



        // You can also verify permissions for specific functions



        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!");



        }



        // Log out



        currentUser.logout();



        System.exit(0);



    }



}



Copy the code

conclusion

  • The above is just a brief introduction to the use of Shiro, including several core concepts, SecurityManager, Session, and Subject

  • What if we don’t want to use the shro.ini configuration file, which we rarely do in real development, so we definitely need to work with the database

  • To solve the problem of not using Shiro. Ini, it’s time to learn more about shiro’s architecture and the configurations it supports