Have you ever felt frustrated when trying to protect your application? Do you feel that existing Java security solutions are difficult to use and will only make you more confused? The Apache Shiro, described in this article, is an unusual Java security framework that provides a simple and powerful way to protect applications. This article also explains the project objectives, architectural concepts and how to use Shiro to escort the application security of Apache Shiro.
What is Apache Shiro? The Apache Shiro (pronounced "shee-roh", the Japanese Fortress (Castle)) is a powerful, Easy-to-use Java security framework that provides authentication, authorization, encryption, and session management capabilities that can provide security for any application-from the command line, Mobile applications to large networks and enterprise applications.
Shiro provides an API for protecting applications to address the following issues (which I like to call the four elements of application security):
Related Vendor Content
Windows Azure officially opens online in China to take the lead in domestic global cloud services, in-depth understanding of Windows Azure Use development test cloud to achieve lean entrepreneurship, rapid iteration Windows Azure self Management Services to achieve nearly 0 downtime to maintain windows Azure Area Online, full understanding of cloud services related sponsors
Windows Azure Zone Online, a comprehensive understanding of the wonderful rendering of cloud services!
• Authentication-user identification, often known as the user "login";
• Authorization-access control;
• Password encryption-protects or hides data from peeping;
• Session Management-The time-sensitive state associated with each user.
Shiro also supports a number of accessibility features, such as Web application security, unit testing, and multithreading, which reinforce the four elements mentioned above.
Why do you want to create Apache Shiro?
The best example of a framework that makes it valuable is the reason why you can use it, and it should be able to do things that others can't. To understand this, you need to know the history of Shiro and other workarounds when creating it.
Before joining the Apache Software Foundation in 2008, Shiro was 5 years old, previously known as the Jsecurity Project, beginning in early 2003. At the time, there was not a lot of universal security alternatives for Java application developers-we were stuck in the Java Authentication/authorization service (or JAAS). Jaas has too many drawbacks-although its authentication function is tolerable, the licensing aspect is clumsy and frustrating. In addition, JAAS is closely related to security issues at the virtual machine level, such as determining whether a class is allowed in the JVM. As an application developer, I'm more concerned with what the application end user can do than what my code can do in the JVM.
Since I was engaged in application development, I also needed a clean, container-independent session mechanism. At the time, the only session available in the game was httpsessions, which required a Web container, or a stateful session bean in EJB 2.1, which also had an EJB container. And the one I want to decouple from the container, can be used for any session in the environment I choose.
The last is the encryption problem. Sometimes we need to secure the data, but the Java cipher architecture (Java Cryptography Architecture) is hard to understand unless you're a cryptography expert. The API is full of checked Exception, which is cumbersome to use. I need a clean, out-of-the-box solution that can easily encrypt/decrypt data when needed.
So, looking at the security situation at the beginning of 2003, you will soon realize that there is not a unification framework to meet all of these requirements. In view of this, jsecurity (that is, after the Apache Shiro) was born.
Today, why do you want to use Apache Shiro?
The framework selection has changed a lot since 2003, but there are still compelling reasons to choose Shiro today. In fact, the reason is quite many, Apache Shiro:
• Ease of use-ease-of-use is the ultimate goal of this project. Application security can be very confusing, frustrating, and considered a "necessary evil": metaphor applies security programming. 】。 It will be no longer a pain if it can be simplified so that beginners can get started quickly.
• Breadth-no other security framework can reach the scope of the Apache Shiro claim, and it can provide a "one-stop" service for your security needs.
• Flexibility-Apache Shiro can work in any application environment. Although it works in the Web, EJB, and IOC environments, it does not depend on these environments. Shiro neither imposes any specification nor relies too much on it.
Web Capabilities-Apache Shiro support for Web applications is amazing, allowing you to create flexible security policies based on application URLs and web protocols such as rest, as well as a set of JSP tag libraries that control page output.
• Pluggable-Shiro clean APIs and design patterns make it easy to integrate with many other frameworks and applications. You will see that Shiro can be seamlessly integrated with third-party frameworks such as spring, Grails, Wicket, Tapestry, Mule, Apache Camel, and Vaadin.
• Support-Apache Shiro is a member of the Apache Software Foundation, a recognized organization that acts to maximize the interests of the community. Both the project development and the user group are friendly members who are ready to provide help. Business companies such as Katasoft can also provide you with the professional support and services you need.
Who's using Shiro?
Shiro and its predecessor, Jsecurity, have been used for many years by companies of various sizes and industries. Since becoming the top project of the Apache Software Foundation, site traffic and usage have continued to grow. Many open source communities are also using Shiro, and here are some examples such as Spring,grails,wicket,tapestry,tynamo,mule and Vaadin.
Commercial companies such as Katasoft,sonatype,mulesoft, a large social network and several New York commercial banks are using Shiro to protect their commercial software and sites.
Core concept: Since Subject,securitymanager and realms have described the benefits of Shiro, let's look at its API so that you can have a perceptual knowledge. The Shiro architecture has three main concepts-subject,securitymanager and realms.
Subject when considering application security, the most common question you may ask is "who is the current user?" "or" is the current user allowed to do x? ”。 When we write code or design a user interface, it's not uncommon to ask yourself these questions: Applications are usually built on user stories, and you want functional descriptions (and security) to be based on each user. So, for us, the most natural way to consider applying security is based on the current user. The Shiro API uses its subject concept to fundamentally reflect this way of thinking.
The term subject is a security term, and its basic meaning is "current operation user". It is not accurate to call it a "user" because the word "user" is usually related to people. In the area of security, the term "Subject" can be a person, a third-party process, a background account (Daemon accounts), or something similar. It simply means "what is currently interacting with the software." But for most purposes and purposes, you can think of it as the "user" concept of Shiro. Anywhere in the code, you can easily get Shiro Subject, see the following code:
Listing 1. Get subject
Copy Code code as follows:
Import Org.apache.shiro.subject.Subject;
Import Org.apache.shiro.SecurityUtils;
...
Subject CurrentUser = Securityutils.getsubject ();
Once you get subject, you can instantly get 90% of what you want to do for your current user, such as login, logout, Access session, perform authorization checks, and more-see more later. The key point here is that the Shiro API is very intuitive because it reflects the natural tendency of developers to think about security controls with ' each user '. At the same time, it is easy to access subject anywhere in the code, allowing for safe operation wherever it is needed.
SecurityManager
Subject's "Behind the scenes" is SecurityManager. Subject represents the security actions of the current user, and SecurityManager manages the security operations of all users. It is the core of the Shiro framework, acting as an "umbrella", referencing multiple internal nested security components that form an object graph. However, once SecurityManager and its internal object map are configured, it takes a back seat, and application developers spend almost all their time on subject API calls.
So, how do you set up SecurityManager? Well, it depends on the application environment. For example, Web applications typically specify a Shiro Servlet Filter in Web.xml, which creates SecurityManager instances, and if you're running a standalone application, you'll need to use other configuration options, but there are many configurations.
An application almost always has only one SecurityManager instance. It is actually the singleton of the application (although it does not have to be a static singleton). As with almost all components in Shiro, the default implementation of SecurityManager is Pojo and can be configured with any POJO compatible configuration mechanism-normal Java code, Spring XML, YAML,. Properties and. ini files, and so on. Basically, any configuration form that can instantiate a class and invoke a JavaBean compatible method can be used.
To do this, Shiro provides a default "public" solution with the help of a text-based ini configuration. INI is easy to read, easy to use, and requires very little reliance. You can also see that if you simply understand object navigation, INI can be effectively used to configure a simple object graph like SecurityManager. Note that Shiro also supports the spring XML configuration and other ways, but here we only discuss INI.
The following Listing 2 lists the Shiro configuration based on INI:
Listing 2. Configuring Shiro with INI
Copy Code code as follows:
[Main]
CM = Org.apache.shiro.authc.credential.HashedCredentialsMatcher
Cm.hashalgorithm = SHA-512
Cm.hashiterations = 1024
# BASE64 encoding (less text):
Cm.storedcredentialshexencoded = False
Inirealm.credentialsmatcher = $cm
[Users]
JDoe = Twfuiglzigrpc3rpbmd1axnozwqsig5vdcbvbmx5igjpcybyzwfzb2
Asmith = IHNPBMD1BGFYIHBHC3NPB24GZNJVBSBVDGHLCIBHBXNOZWQSIG5VDCB
In Listing 2, we see an example of the INI configuration used to configure the SecurityManager instance. There are two INI paragraphs: [main] and [users].
The [main] paragraph is where you configure the SecurityManager object and any other objects that it uses, such as realms. In the example, we saw that two objects were configured:
- CM Object, a Hashedcredentialsmatcher class instance of Shiro. As you can see, the properties of the CM instance are configured through the "nested point" syntax-the conventions used by Inisecuritymanagerfactory are seen in Listing 3, which represents the object graph navigation and property settings.
- Inirealm object, which is securitymanager to represent a user account defined in INI format.
The [users] paragraph is where you specify a static list of user accounts-convenient for simple applications or tests.
As far as the introduction is concerned, the details of each paragraph are not important. Conversely, it is critical to see the INI configuration as a simple way to configure Shiro. For more details on the INI configuration, see the Shiro documentation.
Listing 3. Mount Shiro.ini configuration file
Copy Code code as follows:
Import Org.apache.shiro.SecurityUtils;
Import Org.apache.shiro.config.IniSecurityManagerFactory;
Import Org.apache.shiro.mgt.SecurityManager;
Import Org.apache.shiro.util.Factory;
...
1. Mount INI Configuration
factory<securitymanager> Factory = new Inisecuritymanagerfactory ("Classpath:shiro.ini");
2. Create SecurityManager
SecurityManager SecurityManager = Factory.getinstance ();
3. To make it accessible
Securityutils.setsecuritymanager (SecurityManager); In the example in Listing 3, we see three steps:
- Mount the INI configuration file used to configure SecurityManager and its constituent components;
- Create a SecurityManager instance based on configuration (using the factory concept of Shiro, which describes the factory method design pattern);
- Make the application accessible to SecurityManager Singleton. In this simple example, we set it to VM static Singleton, but this is usually not necessary-your application configuration mechanism can determine whether you need to use static storage.
Realms
The third and final concept of Shiro is Realm. Realm acts as a "bridge" or "connector" between Shiro and application security data. That is, when you are actually interacting with security-related data such as user accounts, performing authentication (login) and authorization (access control), Shiro will look for a lot of content from the realm of the application configuration.
In this sense, realm is essentially a security-related DAO: It encapsulates the connection details of the data source and provides the relevant data to Shiro when needed. When configuring Shiro, you must specify at least one realm for authentication and/or authorization. Configuring multiple realm is possible, but requires at least one.
Shiro has built-in realm that can connect a large number of secure data sources (also known as directories), such as LDAP, relational database (JDBC), text configuration resources like INI, and property files. If the default realm does not meet the requirements, you can also insert your own realm implementation that represents the custom data source. Listing 4 Below is an example of using the LDAP directory as an application realm through the INI configuration Shiro.
Listing 4. Realm Configuration Sample fragment: LDAP that connects to store user data
Copy Code code as follows:
[Main]
Ldaprealm = Org.apache.shiro.realm.ldap.JndiLdapRealm
Ldaprealm.userdntemplate = uid={0},ou=users,dc=mycompany,dc=com
LdapRealm.contextFactory.url = ldap://ldaphost:389
LdapRealm.contextFactory.authenticationMechanism = Digest-md5
Now that you know how to build a basic Shiro environment, let's discuss how you can use this framework as a developer.
Authentication authentication is the process of verifying the identity of the user. That is, when a user authenticates with an application, they are proving that they are the person they are talking about. Sometimes this is also understood as "login." It is a typical three-step process.
1. The collection of user identity information, known as the Parties (principal), as well as the identity of the support certificate, known as Certificates (credential).
2. Submission of Parties and certificates to the system.
3. If the submitted certificate matches the user's identity (the party) as expected by the system, the user is considered certified and, conversely, is not considered certified.
A common example of this process is the familiar "user/password" combination. Most users usually provide their own username (the client) and the password (certificate) to support them when they log on to the software system. If the password (or password) stored in the system matches the user's offer, they are considered authenticated.
Shiro supports the same process in a simple and intuitive way. As we said earlier, Shiro has a subject-centric API-almost everything you want to do with Shiro at run time can be achieved by interacting with the currently executing subject. Therefore, to log in to subject, simply call its login method, passing in a authenticationtoken instance of the representation being submitted to the party and the certificate (in this case, the username and password). Examples are shown in Listing 5:
Listing 5. Subject Login
Copy Code code as follows:
1. Acceptance of Parties and certificates submitted:
Authenticationtoken token =
New Usernamepasswordtoken (username, password);
2. Get current Subject:
Subject CurrentUser = Securityutils.getsubject ();
3. Login:
Currentuser.login (token);
As you can see, the Shiro API is an easy way to reflect this common process. You will continue to see this simple style in all subject operations. After the login method is invoked, SecurityManager receives the Authenticationtoken and sends it to the configured realm to perform the necessary authentication checks. Each realm can respond to the submitted authenticationtokens when necessary. But what happens if the login fails? What happens if the user provides an incorrect password? By reacting to the run-time authenticationexception of Shiro, you can control the failure, as shown in Listing 6.
Listing 6. To control failed logins
Copy Code code as follows:
3. Login:
try {
Currentuser.login (token);
catch (Incorrectcredentialsexception ice) {
...
catch (Lockedaccountexception Lae) {
...
}
...
catch (Authenticationexception ae) {...
}
You can choose to capture a subclass of Authenticationexception, make a specific response, or do a general deal with any authenticationexception (for example, messages that show the user a common "bad username or password"). The choice is in you, you can make a choice according to the application.
After the subject login is successful, they are considered certified and usually you will allow them to use your application. But just proving a user's identity doesn't mean they can do whatever you want with your application. This raises another question, "How do I control what users can or cannot do?" "The process of deciding what the user is allowed to do is called authorization. Below we will talk about how to authorize Shiro.
Authorization is essentially access control-controlling what users can access in the application, such as resources, Web pages, and so on. Most users perform access control by using concepts such as roles and permissions. That is, what is usually allowed or disallowed by the user is determined by the roles or permissions assigned to them. Then, by examining these roles and permissions, your application can control which features are exposed. As you would expect, the Subject API makes it easy to perform roles and permissions checks. As shown in the code fragment in Listing 7: How to check that subject is assigned a role:
Listing 7. Role check
Copy Code code as follows:
if (Subject.hasrole ("Administrator")) {
Show ' Create User ' button
} else {
Button Ash?
}
As you can see, your application may turn on or off some features based on access control checks.
Permission checking is another way to perform authorization. The role check in the example above has a major flaw: you cannot delete and remove roles at run time. The character name is hard-coded here, so if you change the role name or configuration, your code will be messed up! If you need to change the meaning of a role at run time, or want to delete and modify roles, you have to do something different.
To do this, Shiro supports the concept of permissions (permissions). Permission is the original expression of the function, such as ' Open the door ', ' Create a blog ', ' delete ' jsmith ' user ' and so on. By allowing permissions to reflect the original functionality of the application, you only need to change the permissions check when you change the application functionality. In turn, you can assign permissions to roles or users on demand at run time.
In Listing 8, we rewrite the previous user check and use the permission check instead.
Listing 8. Permission check
Copy Code code as follows:
if (subject.ispermitted ("User:create")) {
Show ' Create User ' button
} else {
Button Ash?
}
In this way, any role or user with "User:create" privileges can click the ' Create User ' button, and these roles and assignments can even be changed at run time, which gives you a very flexible security model.
The "User:create" string is an example of a permission string that follows a specific parsing convention. Shiro uses its wildcardpermission to support this out-of-the-box practice. Although this is beyond the scope of this article, you will see that when you create a security policy, wildcardpermission is very flexible and even supports features such as instance-level access control.
Listing 9. Instance-level permission checks
Copy Code code as follows:
if (subject.ispermitted ("User:delete:jsmith")) {
Delete ' jsmith ' user
} else {
Do not delete ' jsmith '
}
This example shows that you can access control of the individual resources you need, and even drill down to very fine-grained instance levels. If you want, you can even invent your own permission syntax. See the Shiro permission documentation for more information. Finally, as with authentication, the above call eventually turns to SecurityManager, which consults realm to make its own access control decisions. When necessary, a single realm is also allowed to respond to both authentication and authorization actions.
The above is a brief overview of the Shiro authorization feature. While most security frameworks stop at authorization and authentication, Shiro provides more functionality. Next, we'll talk about Shiro's advanced session management capabilities.
Session management in the context of the security framework, Apache Shiro provides something unique: it can use the session API consistently at any application or architecture level. That is, Shiro provides a conversational programming paradigm for any application-from a small background to a large cluster Web application. This means that the application developers who want to use the session need not be forced to use a servlet or EJB container. Or, if you are using these containers, developers can now choose to use the session APIs that are consistent at any level to replace the servlet or EJB mechanism.
But perhaps one of the most important benefits of Shiro conversations is that they are independent of the container. This has a subtle but very powerful effect. For example, let's consider the session cluster. How many container-specific ways are there to support fault tolerance and failover for cluster sessions? Tomcat is different from jetty, and jetty is not the same as WebSphere, and so on. But through the Shiro session, you can get a container-independent cluster solution. The Shiro architecture allows pluggable session data storage, such as enterprise caching, relational databases, NoSQL systems, and so on. This means that once the session cluster is configured, it will work in the same way, regardless of the deployment environment-TOMCAT, Jetty, JEE Server, or standalone application. No matter how you deploy the application, you do not need to reconfigure it.
Another benefit of Shiro sessions is that session data can be shared across client technologies, if needed. For example, swing desktop clients can participate in the same Web application session when needed-which is useful if the end user uses both applications. So how do you access subject's conversations in any environment? Take a look at the example below, which uses the two methods of subject.
Listing 10. Subject's session
Copy Code code as follows:
Session session = Subject.getsession ();
Session session = Subject.getsession (Boolean create);
As you can see, these methods are conceptually equivalent to the HttpServletRequest API. The first method returns an existing session of subject, or if there is no session, it creates a new one and returns it. The second method accepts a Boolean parameter that is used to determine whether a new session is created when the conversation does not exist. Once you get a Shiro session, you can use it almost as if you were using HttpSession. The Shiro team felt that the HttpSession API was very comfortable for Java developers, so we kept a lot of its senses. The big difference, of course, is that you can use Shiro sessions in any application, not just web apps. This similarity is shown in Listing 11.
Listing 11. Methods of the session
Copy Code code as follows:
Session session = Subject.getsession ();
Session.getattribute ("Key", somevalue);
Date start = Session.getstarttimestamp ();
Date timestamp = Session.getlastaccesstime ();
Session.settimeout (Millis); ...
Cryptographic encryption is the process of hiding or confusing data to avoid being spied on. In the area of cryptography, the goal of Shiro is to simplify and make the JDK encryption support available.
It is important to be clear that, in general, encryption is not specific to subject, so it is part of the Shiro API, but is not specific to subject. You can use Shiro encryption support anywhere, even without using subject. For cryptographic support, the two areas that Shiro really focus on are cryptographic hashes (also known as message digests) and encrypted passwords. Let's take a look at the detailed descriptions of these two aspects.
Hash if you've ever used JDK's messagedigest class, you'll immediately realize that it's a bit of a hassle to use. The MessageDigest class has an unwieldy, factory-based static method API that is not object-oriented, and you are forced to capture checked exceptions that you never have to capture. If you need to output hexadecimal-encoded or BASE64-encoded message digests, you are only on your own-there are no standard JDK support for both of these encodings. Shiro solves the above problem with a clean, intuitive hash API.
For example, consider a more common scenario, hash a file with MD5, and determine the hexadecimal value of the hash. Called ' checksum ', which is often used to provide file downloads-users can perform their own MD5 hashes on downloaded files. If they match, the user can fully assume that the file has not been tampered with during transmission.
Do not use Shiro, you need the following steps to complete the above content:
1. Converts a file into a byte array. There's no such thing in the JDK, so you need to create an auxiliary method that opens the FileInputStream, uses the byte buffer, throws the associated ioexceptions, and so on.
2. Hash the byte array using the MessageDigest class, handling the associated exception, as shown in Listing 12.
3. Encodes the hashed byte array into hexadecimal characters. There is no such thing in JDK, you still need to create another helper method, it is possible to use bit manipulation and bit movement in your implementation.
Listing 12. Message Digest for JDK
Copy Code code as follows:
try {
MessageDigest MD = messagedigest.getinstance ("MD5");
Md.digest (bytes);
byte[] hashed = Md.digest ();
catch (NoSuchAlgorithmException e) {
E.printstacktrace ();
}
This is a huge workload for such a simple and general demand. Now let's see how Shiro does the same thing:
String hex = new Md5hash (myFile). Tohex ();
When using Shiro to simplify all this work, everything is simple and straightforward. It is also as easy to complete the Base64 encoding of SHA-512 hashes and passwords.
String Encodedpassword = new Sha512hash (password, salt, count). ToBase64 ();
You can see that Shiro simplifies hashing and coding, and saves you the brain cells that you use to deal with such problems.
Password encryption is a cryptographic algorithm that uses a key to reversibly convert data. We use it to keep data safe, especially when it comes to transmitting or storing data, and when data is easily spied upon.
If you've ever used JDK's cryptography API, especially the Javax.crypto.Cipher class, you'll know it's a very complex beast that needs to be tamed. For starters, each possible cryptographic configuration is always represented by a javax.crypto.Cipher instance. Must public/private key encryption be performed? You have to use cipher. Need to use block cipher for streaming operations (blocks Cipher)? You have to use cipher. Need to create an AES 256-bit cipher to protect the data? You have to use cipher. You know.
So how do you create the cipher instance you need? You have to create an transformation, delimited cryptographic option string called a "conversion string" that passes the string to the Cipher.getinstance static factory method. The cipher option for this string approach does not have type safety to ensure that you are using a valid option. This also implies that there is no javadoc to help you understand the relevant options. Also, if the string format is not properly organized, you will need to deal with checked Exception even if you know the configuration is correct. As you can see, using JDK cipher is a pretty heavy task. Once upon a time, these technologies were the standard of the Java API, but as things changed, we needed a simpler approach.
Shiro attempts to simplify the entire concept of cryptographic passwords by introducing its Cipherservice API. Cipherservice is what most developers crave when it comes to protecting data: a simple, stateless, thread-safe API that encrypts or decrypts the entire data in one method call. All you need to do is to provide your key, which can be encrypted or decrypted as needed. Use 256-bit AES encryption, as shown in listing 13 below:
Listing 13. The Apache Shiro Encryption API
Copy Code code as follows:
Aescipherservice cipherservice = new Aescipherservice ();
Cipherservice.setkeysize (256);
To create a test key:
byte[] TestKey = Cipherservice.generatenewkey ();
bytes of encrypted File:
Byte[] encrypted = Cipherservice.encrypt (filebytes, TestKey);
The example of cipher Api,shiro compared to JDK is much simpler:
• You can directly instantiate a cipherservice-no strange or confusing factory approach;
cipher configuration options can be expressed as JavaBean-compatible getter and setter methods-without strange and incomprehensible "conversion strings";
• Encryption and decryption are done in a single method call;
• Checked Exception not imposed. If you want, you can capture the Shiro cryptoexception.
Shiro's Cipherservice API also has other benefits, such as supporting byte-array encryption/decryption (called "block" operations) and stream based encryption/decryption (such as encrypted audio or video).
No longer have to endure the pain of Java cryptography. Shiro's cryptography support is designed to reduce your efforts to ensure data security.
Web support Last but not unimportant, we will give a brief introduction to Shiro Web support. Shiro comes with a strong web support module that helps protect Web applications. For Web applications, installing Shiro is simple. The only thing to do is to define a Shiro servlet filter in Web.xml. In Listing 14, the code is listed.
Listing 14. The Shirofilter in the Web.xml
Copy Code code as follows:
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>
Org.apache.shiro.web.servlet.IniShiroFilter
</filter-class>
<!--no Init-param property means Mount INI configuration from Classpath:shiro.ini-->
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
This filter can read the above Shiro.ini configuration so that you have a consistent configuration experience regardless of the development environment. Once the configuration is complete, Shiro filter filters each request and ensures that the subject of the particular request is accessible during the request. And because it filters each request, you can execute security-specific logic to ensure that only requests that meet a certain standard are allowed to pass.
URL-specific filter chain
Shiro supports security-specific filtering rules through its innovative URL filter chain features. It allows you to specify an informal filter chain for any matching URL pattern. This means that, using the Shiro filter mechanism, you can be flexible in enforcing security rules (or combinations of rules)-far more than you get when you define filters alone in Web.xml. The configuration fragment in Shiro INI is shown in Listing 15.
Listing 15. Path-specific filter chain
Copy Code code as follows:
[URLs]
/assets/** = Anon
/user/signup = Anon
/user/** = user
/rpc/rest/** = Perms[rpc:invoke], authc
/** = authc
As you can see, Web applications use the [url] ini paragraph. For each row, the value to the left of the equal sign represents the Web application path for the relative context. The value to the right of the equal sign defines the filter chain-a comma-delimited list of ordered servlet filters that are executed for the given path. Each filter is a normal servlet filter, and the top filter name (ANON,USER,PERMS,AUTHC) You see is the Shiro built-in security-related special filter. You can match these security filters to create a highly customizable security experience. You can also specify any other existing servlet filters.
What are the benefits of this approach compared to using Web.xml, where you define the filter block first, and then define separate filter pattern blocks? With the Shiro approach, it is easy to know exactly what filter chains are executed for a given matching path. If you want to do this, you can define only Shiro filter in the Web.xml, define all the other filters and filter chains in Shiro.ini, which is much simpler than web.xml, and it's easier to understand the definition mechanism of the filter chain. Even if you do not use any of the security features of Shiro, it is worth your while to use Shiro for this small convenience.
JSP Tag Library
Shiro also provides a JSP tag library that allows you to control the output of JSP pages based on the current subject status. A useful common example is to display the "Hello <username>" text after the user logs on. But if you are an anonymous user, you may want to display other content, such as "hello! Register today! ". Listing 16 shows how to use the Shiro JSP tag to implement this example:
Listing 16. JSP Tag Library Sample
Copy Code code as follows:
<%@ taglib prefix= "Shiro"
Uri= "Http://shiro.apache.org/tags"%>
...
<p>hello
<shiro:user>
<!--Shiro:principal Print out subject's main client-in this case, the user name:-->
<shiro:principal/>!
</shiro:user>
<shiro:guest>
<!--is not logged in-it is considered guest. Show Registration Link:-->
! <a href= "register.jsp" >register today!</a>
</shiro:guest>
</p>
In addition to the tags used in the example above, there are other tags that allow you to assign (or not assign) permissions based on the user's (or not) role, whether they are authenticated, whether they come from memory of the "Remember Me" service, or anonymous visitors, including output.
Shiro also supports many other web features, such as the Simple "Remember Me" service, rest and Basic authentication. Of course, it also provides transparent httpsession support if you want to use a Shiro native enterprise session. See the Apache Shiro Web documentation for more information.
Web Session Management
Finally, it is worth mentioning that Shiro support for sessions in a Web environment.
Default HTTP session
For Web applications, Shiro defaults to use the servlet container session that we take for granted as its session infrastructure. That is, when you invoke the Subject.getsession () and Subject.getsession (Boolean) methods, Shiro returns the session instance supported by the HttpSession instance of the servlet container. The beauty of this approach is that the business layer code that invokes subject.getsession () interacts with a Shiro session instance-not yet "aware" that it is dealing with a web-based httpsession. This is a great thing to do when maintaining a clear separation between the architecture layers.
Native session of Shiro in Web layer
If you open Shiro native session management because of the need for Shiro Enterprise session features (such as container-independent clusters), you certainly want Httpservletrequest.getsession () and HttpSession APIs to collaborate with "native" sessions, Rather than a servlet container session. It would be frustrating if you had to refactor all the code using the HttpServletRequest and HttpSession APIs and replace it with the Shiro session API. Shiro certainly never expected you to do that. Instead, Shiro fully implements the session section of the servlet specification to support native sessions in Web applications. This means that whenever you use the appropriate HttpServletRequest or HttpSession method calls, Shiro delegates these calls to the internal native session API. As a result, you do not need to modify the Web code, even if you are using Shiro's ' native ' enterprise session management-a very handy (and necessary) feature.
Additional attributes
The Apache Shiro Framework also includes other features that are useful for protecting Java applications, such as:
- Provides threading and concurrency support (support for executor and Executorservice) to maintain suject across threads;
- In order to implement logic as a special subject, the callable and runnable interfaces are supported;
- Support for "Run as" (e.g., useful in management applications) in order to represent another subject identity;
- Support test tools that make it easy to unit test and integrate testing of Shiro security code.
Framework Limitations
Common sense tells us that Apache Shiro is not a "silver bullet"-it does not effortlessly solve all security problems. The following are Shiro that have not been resolved, but are worth knowing:
- problem at the virtual machine level : Apache Shiro is not currently dealing with virtual machine level security, such as preventing class loaders from loading a class based on access control policies. However, Shiro integration of existing JVM security operations is not a daydream-just no one has contributed to the project.
- Multi-stage authentication : At present, Shiro does not support "multistage" authentication, that is, the user may log in through a mechanism, and when asked to log in again, use another mechanism to log in. This has been implemented in Shiro applications, but the application collects all the necessary information in advance and then interacts with the Shiro. This feature is very likely to be supported in future versions of Shiro.
- Realm write : All realm implementations currently support "read" Operations to obtain authentication and authorization data to perform login and access control. Write operations such as creating user accounts, groups and roles, or user-related role groups and permissions are not supported. This is because the application data model that supports these operations has changed so much that it is difficult to enforce a "write" API for all Shiro users.
The characteristics of the future
The Apache Shiro community is growing every day, and so is the Shiro characteristic. In the upcoming release, you might see:
- Cleaner web filtering mechanisms that support more plug-in filters without the need to subclass.
- More pluggable default realm implementations that take precedence over combinations rather than inheritance. You can insert components that look up authentication and authorization data without implementing a subclass of Shiro realm;
- Robust OpenID and OAuth (possibly mixed) client support;
- Support Captcha;
- Configuration simplification for purely stateless applications (e.g., many rest environments);
- Multi-stage authentication through a request/response protocol;
- The authorization of coarse granularity through authorizationrequest;
- ANTLR syntax for Security assertion queries (for example, (' Role (admin) && (Guest | |!group (DEVELOPER)) ')
Summarize
The Apache Shiro is a full-featured, robust, general-purpose Java security framework that you can use to escort your application. By simplifying the four areas of application security, authentication, authorization, session management, and encryption, application security can be more easily understood and implemented in real-world applications. Shiro's simple architecture and compatible javabean enable it to be configured and used in virtually any environment. Additional Web support and accessibility features, such as multithreading and test support, allow this framework to provide a "one-stop" service for application security. The Apache Shiro development team will move on, refining the code base and supporting the community. With the continued adoption of open source and commercial applications, Shiro can be expected to continue to grow and develop.
Resources
- The home page of the Apache Shiro.
- Shiro's download page, which contains additional information for MAVEN and Ant+ivy users.
- The Apache Shiro documentation page that contains guides and reference manuals.
- Apache Shiro Lectures video and slideshow, the project's PMC chairman Les Hazlewood offers.
- Other articles and slides about Apache Shiro
- Apache Shiro mailing lists and forums.
- Katasoft-provides Apache Shiro Professional support and application of security products company.
About the author
Les Hazlewood is the Apache Shiro PMC Chairman and Katasoft's CTO and co-founder, a start-up company focused on applying security products and providing professional support for Apache Shiro. As a professional Java developer and Enterprise Architect, as well as the senior role of Bloomberg,delta Airlines and JBoss, Les has 10 years of experience. Les has been active in open source development for 9 years, and has submitted or contributed to the spring framework, Hibernate, Jboss,openspaces, and of course the predecessor of Jsecurity,apache Shiro. Les currently lives in San Mateo, California, where he practises kendo and learns Japanese when he is not programmed.
View English Original: Application Security with Apache Shiro
Thank Hu Yu for the revision of this article.