shiro 简介

笔者相信官方文档和源码时最佳的学习资料,以下摘抄自官网介绍

一.What is Apache Shiro

Apache Shiro (pronounced “shee-roh”, the Japanese word for ‘castle’) is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management and can be used to secure any application - from the command line applications, mobile applications to the largest web and enterprise applications.

shiro 可以在command line、mobile application、web 中使用的安全框架,其中有4个核心组件。

Shiro provides the application security API to perform the following aspects (I like to call these the 4 cornerstones of application security):

Authentication - proving user identity, often called user ‘login’.
Authorization - access control
Cryptography - protecting or hiding data from prying eyes
Session Management - per-user time-sensitive state

二.Core Concepts: Subject, SecurityManager, and Realms

1.Subject

When you’re securing your application, probably the most relevant questions to ask yourself are, “Who is the current user” or “Is the current user allowed to do X” It is common for us to ask ourselves these questions as we’re writing code or designing user interfaces: applications are usually built based on user stories, and you want functionality represented (and secured) based on a per-user basis. So, the most natural way for us to think about security in our application is based on the current user. Shiro’s API fundamentally represents this way of thinking in its Subject concept.

The word Subject is a security term that basically means “the currently executing user”. It’s just not called a ‘User’ because the word ‘User’ is usually associated with a human being. In the security world, the term ‘Subject’ can mean a human being, but also a 3rd party process, daemon account, or anything similar. It simply means ‘the thing that is currently interacting with the software’. For most intents and purposes though, you can think of this as Shiro’s ‘User’ concept. You can easily acquire the Shiro Subject anywhere in your code as shown in Listing 1 below.

Update on using Apache Shiro
Pairing Apache Shiro and Java EE 7 - Learn how to use Shiro in a JavaEE7 application and how to use it in a web application. Download the FREE gudeide.

Are you frustrated when you try to secure your applications Do you feel existing Java security solutions are difficult to use and only confuse you further This article introduces Apache Shiro, a Java security framework that provides a simple but powerful approach to application security. It explains Apache Shiro’s project goals, architectural philosophies and how you might use Shiro to secure your own applications.

What is Apache Shiro
RELATED VENDOR CONTENT
DevOps Success Requires Shift-Right Testing in Production – Download the Gartner Report
Manual Monitoring Bad! Automatic Monitoring Good!
Monitor your applications built in Java, .NET , Ruby, PHP and Node.js
Managing Feature Flags - Download the eBook (By O’Reilly)
Obtain a holistic view of your application behaviour and troubleshoot errors with Site24x7
RELATED SPONSOR

GitLab is a single application for the entire software development lifecycle. Try GitLab for free.

Apache Shiro (pronounced “shee-roh”, the Japanese word for ‘castle’) is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management and can be used to secure any application - from the command line applications, mobile applications to the largest web and enterprise applications.

Shiro provides the application security API to perform the following aspects (I like to call these the 4 cornerstones of application security):

Authentication - proving user identity, often called user ‘login’.
Authorization - access control
Cryptography - protecting or hiding data from prying eyes
Session Management - per-user time-sensitive state
Shiro also supports some auxiliary features, such as web application security, unit testing, and multithreading support, but these exist to reinforce the above four primary concerns.

Why was Apache Shiro created
For a framework to really make a good case for its existence, and therefore a reason for you to use it, it should satisfy needs that aren’t met by other alternatives. To understand this, we need to look at Shiro’s history and the alternatives when it was created.

Before entering the Apache Software Foundation in 2008, Shiro was already 5 years old and previously known as the JSecurity project, which started in early 2003. In 2003, there weren’t many general-purpose security alternatives for Java application developers - we were pretty much stuck with the Java Authentication and Authorization Service, otherwise known as JAAS. There were a lot of shortcomings with JAAS - while its authentication capabilities were somewhat tolerable, the authorization aspects were obtuse and frustrating to use. Also, JAAS was heavily tied to Virtual Machine-level security concerns, for example, determining if a class should be allowed to be loaded in the JVM. As an application developer, I cared more about what an application end-user could do rather than what my code could do inside the JVM.

Due to the applications I was working with at the time, I also needed access to a clean, container-agnostic session mechanism. The only session choices in the game at the time were HttpSessions, which required a web container, or EBJ 2.1 Stateful Session Beans, which required an EJB container. I needed something that could be decoupled from the container, usable in any environment I chose.

Finally, there was the issue of cryptography. There are times when we all need to keep data secure, but the Java Cryptography Architecture was hard to understand unless you were a crypto expert. The API was full of checked exceptions and felt cumbersome to use. I was hoping for a cleaner out-of-the-box solution to easily encrypt and decrypt data as necessary.

So looking at the security landscape of early 2003, you can quickly realize that there was nothing that could satisfy all of those requirements in a single, cohesive framework. Because of that, JSecurity, and then later, Apache Shiro, was born.

Why would you use Apache Shiro today
The framework landscape has changed quite a bit since 2003, so there should still be a compelling reason to use Shiro today. There are quite a few reasons actually. Apache Shiro is:

Easy To Use - Ease of use is the project’s ultimate goal. Application security can be extremely confusing and frustrating and thought of as a ‘necessary evil’. If you make it so easy to use that novice programmers can start using it, it doesn’t have to be painful anymore.
Comprehensive - There is no other security framework with the breadth of scope that Apache Shiro claims, so it can likely be your ‘one stop shop’ for your security needs.
Flexible - Apache Shiro can work in any application environment. While it works in web, EJB, and IoC environments it does not require them. Nor does Shiro mandate any specification or even have many dependencies.
Web Capable - Apache Shiro has fantastic web application support, allowing you to create flexible security policies based on application URLs and web protocols (e.g. REST), while also providing a set of JSP libraries to control page output.
Pluggable - Shiro’s clean API and design patterns make it easy to integrate with many other frameworks and applications. You’ll see Shiro integrated seamlessly with frameworks like Spring, Grails, Wicket, Tapestry, Mule, Apache Camel, Vaadin, and many others.
Supported - Apache Shiro is part of the Apache Software Foundation, an organization proven to act in the best interest of its community. The project development and user groups have friendly citizens ready to help. Commercial companies like Katasoft also provide professional support and services if desired.
Who’s Using Shiro
Shiro and its predecessor JSecurity has been in use for years in projects for companies of all sizes and across industries. Since becoming an Apache Software Foundation Top Level Project, site traffic and adoption have continued to grow significantly. Many open-source communities are using Shiro as well, for example, Spring, Grails, Wicket, Tapestry, Tynamo, Mule, and Vaadin, just to name a few.

Commercial companies like Katasoft, Sonatype, MuleSoft, one of the major social networks, and more than a few New York commercial banks use Shiro to secure their commercial software and websites.

Core Concepts: Subject, SecurityManager, and Realms
Now that we’ve covered Shiro’s benefits, let’s jump right in to its API so you can get a feel for it. Shiro’s architecture has three main concepts - the Subject, the SecurityManager, and Realms.

Subject
When you’re securing your application, probably the most relevant questions to ask yourself are, “Who is the current user” or “Is the current user allowed to do X” It is common for us to ask ourselves these questions as we’re writing code or designing user interfaces: applications are usually built based on user stories, and you want functionality represented (and secured) based on a per-user basis. So, the most natural way for us to think about security in our application is based on the current user. Shiro’s API fundamentally represents this way of thinking in its Subject concept.

The word Subject is a security term that basically means “the currently executing user”. It’s just not called a ‘User’ because the word ‘User’ is usually associated with a human being. In the security world, the term ‘Subject’ can mean a human being, but also a 3rd party process, daemon account, or anything similar. It simply means ‘the thing that is currently interacting with the software’. For most intents and purposes though, you can think of this as Shiro’s ‘User’ concept. You can easily acquire the Shiro Subject anywhere in your code as shown in Listing 1 below.

subject代表当前操作某个功能的主体(登录的用户等)

import org.apache.shiro.subject.Subject;
import org.apache.shiro.SecurityUtils;
 
Subject currentUser = SecurityUtils.getSubject();

Once you acquire the Subject, you immediately have access to 90% of everything you’d want to do with Shiro for the current user, such as login, logout, access their session, execute authorization checks, and more - but more on this later. The key point here is that Shiro’s API is largely intuitive because it reflects the natural tendency for developers to think in ‘per-user’ security control. It is also easy to access a Subject anywhere in code, allowing security operations to occur anywhere they are needed

2.SecurityManager

While the Subject represents security operations for the current user, the SecurityManager manages security operations for all users. It is the heart of Shiro’s architecture and acts as a sort of ‘umbrella’ object that references many internally nested security components that form an object graph. However, once the SecurityManager and its internal object graph is configured, it is usually left alone and application developers spend almost all of their time with the Subject API.

Subject 代表当前用户的安全操作,SecurityManager 为所有用户管理安全操作

So how do you set up a SecurityManager Well, that depends on your application environment. For example, a web application will usually specify a Shiro Servlet Filter in web.xml, and that will set up the SecurityManager instance. If you’re running a standalone application, you’ll need to configure it another way. But there are many of configuration options.

There is almost always a single SecurityManager instance per application. It is essentially an application singleton (although it does not need to be a static singleton). Like almost all things in Shiro, the default SecurityManager implementations are POJOs and are configurable with any POJO-compatible configuration mechanism - normal Java code, Spring XML, YAML, .properties and .ini files, etc. Basically anything that is capable of instantiating classes and calling JavaBeans-compatible methods may be used.

一个应用总是有一个SecurityManager 单例

Configuring Shiro with INI

[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

The [main] section is where you configure the SecurityManager object and/or any objects (like Realms) used by the SecurityManager. In this example, we see two objects being configured:

1.The cm object, which is an instance of Shiro’s HashedCredentialsMatcher class. As you can see, various properties of the cm instance are being configured via ‘nested dot’ syntax - a convention used by the IniSecurityManagerFactory shown in Listing 3, to represent object graph navigation and property setting.

2.The iniRealm object, which is a component used by the SecurityManager to represent user accounts defined in the INI format.

INI 配置文件是分段的,如上就是配置一个main 段,其中cm 是定义一个对象,$cm 是引用该对象并调用iniReam 的 credentialsMatcher setter方法设置值(类似spring 的xml 文件中bean 的定义和依赖注入)。

The [users] section is where you can specify a static list of user accounts - convenient for simple applications or when testing.

users 段配置静态用户账号

Loading shiro.ini Configuration File

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.util.Factory;

//1. Load the INI configuration
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");

//2. Create the SecurityManager
SecurityManager securityManager = factory.getInstance();

//3. Make it accessible
SecurityUtils.setSecurityManager(securityManager);

3.Realms

A Realm acts as the ‘bridge’ or ‘connector’ between Shiro and your application’s security data. That is, when it comes time to actually interact with security-related data like user accounts to perform authentication (login) and authorization (access control), Shiro looks up many of these things from one or more Realms configured for an application.

reaml 作为沟通Shiro 和应用安全数据的桥梁,例如提供用户登录和授权

In this sense a Realm is essentially a security-specific DAO: it encapsulates connection details for data sources and makes the associated data available to Shiro as needed. When configuring Shiro, you must specify at least one Realm to use for authentication and/or authorization. More than one Realm may be configured, but at least one is required.

配置shiro 需要提供至少一个realm 做为认证或授权

Shiro provides out-of-the-box Realms to connect to a number of security data sources (aka directories) such as LDAP, relational databases (JDBC), text configuration sources like INI and properties files, and more. You can plug-in your own Realm implementations to represent custom data sources if the default Realms do not meet your needs. Listing 4 below is an example of configuring Shiro (via INI) to use an LDAP directory as one of the application’s Realms.

shiro 也提供了其他realm配置,jdbc、ini等

三.Authentication

Authentication is the process of verifying a user’s identity. That is, when a user authenticates with an application, they are proving they actually are who they say they are. This is also sometimes referred to as ‘login’. This is typically a three-step process.

1.Collect the user’s identifying information, called principals, and supporting proof of identity, called credentials.

2.Submit the principals and credentials to the system.

3.If the submitted credentials match what the system expects for that user identity (principal), the user is considered authenticated. If they don’t match, the user is not considered authenticated.

A common example of this process that everyone is familiar with is that of the username/password combination. When most users login to a software application, they usually provide their username (the principal) and their supporting password (the credential). If the password (or representation of it) stored in the system matches what the user specifies, they are considered authenticated.

//1. Acquire submitted principals and credentials:
AuthenticationToken token = new UsernamePasswordToken(username, password);

//2. Get the current Subject:
Subject currentUser = SecurityUtils.getSubject();

//3. Login:
currentUser.login(token);

What if the user specified an incorrect password You can handle failures by reacting to Shiro’s runtime AuthenticationException.

try {
    currentUser.login(token);
} catch (IncorrectCredentialsException ice) { …
} catch (LockedAccountException lae) { …
}
…
catch (AuthenticationException ae) {…
} 

You can choose to catch one of the AuthenticationException subclasses and react specifically, or generically handle any AuthenticationException (for example, show the user a generic “Incorrect username or password” message). The choice is yours depending on your application requirements.

四.Authorization

Authorization is essentially access control - controlling what your users can access in your application, such as resources, web pages, etc. Most users perform access control by employing concepts such as roles and permissions. That is, a user is usually allowed to do something or not based on what roles and/or permissions are assigned to them. Your application can then control what functionality is exposed based on checks for these roles and permissions. As you might expect, the Subject API allows you to perform role and permission checks very easily.

if ( subject.hasRole(“administrator”) ) {
    //show the ‘Create User’ button
} else {
    //grey-out the button?
} 

Permission checks are another way to perform authorization. Checking for roles as in the example above suffers from one significant flaw: you can’t add or delete roles at runtime. Your code is hard-coded with role names, so if you changed the role names and/or configuration, your code would be broken! If you need to be able to change a role’s meaning at runtime, or add or delete roles as desired, you have to rely on something else.

To that end, Shiro supports its notion of permissions. A permission is a raw statement of functionality, for example ‘open a door’, ‘create a blog entry’, ‘delete the ‘jsmith’ user’, etc. By having permissions reflect your application’s raw functionality, you only need to change permission checks when you change your application’s functionality. In turn, you can assign permissions to roles or to users as necessary at runtime.

if ( subject.isPermitted(“user:create”) ) {
    //show the ‘Create User’ button
} else {
    //grey-out the button?
} 

五.Session Management

Apache Shiro provides something unique in the world of security frameworks: a consistent Session API usable in any application and any architectural tier. That is, Shiro enables a Session programming paradigm for any application - from small daemon standalone applications to the largest clustered web applications. This means that application developers who wish to use sessions are no longer forced to use Servlet or EJB containers if they don’t need them otherwise. Or, if using these containers, developers now have the option of using a unified and consistent session API in any tier, instead of servlet or EJB-specific mechanisms.

But perhaps one of the most important benefits of Shiro’s sessions is that they are container-independent. This has subtle but extremely powerful implications. For example, let’s consider session clustering. How many container-specific ways are there to cluster sessions for fault-tolerance and failover Tomcat does it differently than Jetty, which does it differently than Websphere, etc. But with Shiro sessions, you obtain a container-independent clustering solution. Shiro’s architecture allows for pluggable Session data stores, such as enterprise caches, relational databases, NoSQL systems and more. This means that you can configure session clustering once and it will work the same way regardless of your deployment environment - Tomcat, Jetty, JEE Server or standalone application. There is no need to reconfigure your app based on how you deploy your application.

Another benefit of Shiro’s sessions is session data can be shared across client technologies if desired. For example, a Swing desktop client can participate in the same web application session if desired - useful if the end-user is using both simultaneously. So how do you access a Subject’s session in any environment There are two Subject methods as shown in the example below.

Session session = subject.getSession();
Session session = subject.getSession(boolean create);

As you can see, the methods are identical in concept to the HttpServletRequest API. The first method will return the Subject’s existing Session, or if there isn’t one yet, it will create a new one and return it. The second method accepts a boolean argument that determines whether or not a new Session will be created if it does not yet exist. Once you acquire the Subject’s Session, you can use it almost identically to an HttpSession. The Shiro team felt that the HttpSession API was most comfortable to Java developers, so we retained much of its feel. The big difference, of course, is that you can use Shiro Sessions in any application, not just web applications.

总结

以上是笔者从shiro 官网摘抄的官方文档并提供简要的说明。笔者也只能看懂英文的7层左右,查看英文文档资料对软件开发是非常重要的能力,遇到不懂的单词就查,日积月累就能看懂更多的英文文档!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值