Apache Shiro Authentication)
Authentication: The process of authentication-that is, to prove the real identity of a user. To prove the identity of a user, you must provide the identity information and evidence that the system understands and believes.
You need to provide Shiro with the user's identity (principals) and credentials to determine whether it matches the system's requirements.
Identity (principals)It is the "Identity attribute" of a subject. It can be any subject-related identifier, such as the name (given name), name (last name or nickname), user name, and security number, of course, content such as nicknames cannot be uniquely identified for subject, so the best identity information (principals) is the unique identifier in the program-the typical user name or email address.
Primary identity
Although Shiro can use any number of identities, Shiro still wants a program to precisely use a primary identity-a unique value for the subject. In most programs, it is often a user name, email address, or a Globally Unique User ID.
Credentials)Usually only subject knows the confidential content to prove that they really have the desired identity, some simple certificate examples such as password, fingerprint, fundus scan and X.509 Certificate.
The most common identity/proof is the user name and password, the user name is the identity description required, and the password is proof of identity. If a submitted password is the same as the password required by the system, the program considers that the user's identity is correct because others should not know the same password.
Authenticating object
The subject verification process can be effectively divided into the following three steps:
1. Collect the identity and proof submitted by subject;
2. Submit the identity and proof to authenticating;
3. If the submitted content is correct, access is allowed. Otherwise, verify or block access again.
The following code demonstrates how the Shiro API implements these steps:
Step 1: Collect User identities and creden
// Example using mostcommon scenario of username/password pair:
Usernamepasswordtokentoken = new usernamepasswordtoken (username, password );
// "Remember Me" built-in:
Token. setrememberme (true );
Here we use usernamepasswordtoken to support all common user name/password verification methods. This is an org. apache. shiro. authc. the implementation of the authenticationtoken interface, which is used by the Shiro authentication system to submit the identity and proof.
Note that Shiro does not care about how you get these residences: it may be submitted by the user from an HTML form, or it may be parsed from an HTTP request string, it may also come from the swing or flex GUI password form, or through command line parameters. The process of obtaining information from the end user of the program has nothing to do with Shiro's authenticationtoken.
You can construct and reference the authenticationtoken as you like -- it is an unknown protocol.
This example also shows that we want Shiro to execute the "remember me" service during verification attempts, which ensures that Shiro can remember their identities when users return to the system in the future, we will discuss the "remember me" service in a later chapter.
Step 2: Submit your identity and proof
After the identity and domicile creden are collected and instantiated as an authentication token, We need to submit a token to Shiro to perform a real verification attempt:
Subject currentuser = securityutils. getsubject ();
Currentuser. login (token );
After obtaining the currently executed subject, we execute a separate LOGIN command to pass the created authentication token instance to it.
Using the login method will effectively perform authentication.
Step 3: Processing succeeded or failed
If the login function does not return information, the verification is successful. The program can continue running. When securityutils. getsubject () is executed, the verified subject instance is returned, and subject. isauthenticated () returns true.
But what if login fails? For example, what if the user provides a wrong password or is locked due to too many times of access to the system?
Shiro has a wide range of runtime exceptions (authenticationexception) that can precisely identify why verification failed, you can put login into the try/Catch Block, capture all the exceptions you want to catch, and handle them. For example:
Try {
Currentuser. login (token );
} Catch (unknownaccountexception UAE ){...
} Catch (incorrectcredentialsexception ice ){...
} Catch (lockedaccountexception Lae ){...
} Catch (excessiveattemptsexception family ){...
}... Catch your own...
} Catch (authenticationexception AE ){
// Unexpected error?
}
// No problems, continue on as expected...
If the existing exceptions cannot meet your needs, you can create custom authenticationexceptions to indicate specific failure scenarios.
Logon Failure tips
Although your code can handle specified exceptions and execute some of the required logic, experienced security practices are to only output general failure information to end users, for example, "Incorrect username and password ". This ensures that no useful information is provided to hackers who attempt to attack you.
Remembered (remembered) vs verified (authenticated)
As shown in the preceding example, Shiro supports executing "remember me" during logon. It is worth noting that a remembered subject (remembered subject) and a properly authenticated subject (authenticated subject) shiro is totally different.
Remembered: A remembered subject has no known identity (that is, subject. getprincipals () returns NULL), but its identity is remembered by the previous authentication process and exists in the previous session. A remembered object is executing subject. isremembered () returns true.
Authenticated: A verified subject exists in the current session after successful verification (such as successful logon), and a verified object calls subject. isauthenticated () returns true.
Mutually Exclusive
Remember that (remembered) and verified (authenticated) are mutually exclusive-one identification value is false if the other is true, and the opposite is true.
Why?
Word authentication has obvious proof meaning, that is, you need to ensure that the subject has been proved who they are.
When a user is remembered only when interacting with a program, the state of the proof does not exist: the remembered identity only gives the system information about who the user may be, but is not sure, there is no way to guarantee that the remembered subject is the requested user. Once this subject is verified, they are no longer considered to be remembered because their identities have been verified and coexist in the current session.
Therefore, in most cases, a program can still execute user-specific logic for remembered identities, such as custom views, however, do not perform sensitive operations until the user successfully performs authentication to determine the identity.
For example, checking whether a subject can access financial information should depend on whether it is verified (isauthenticated () rather than remembered (isremembered ()), make sure that the subject is required and authenticated.
Example
The following is a common scenario to help illustrate why the difference between being remembered and being verified is important.
Assume that you have successfully logged on to the Apsara stack console and added some books to the shopping blue area. However, if you want to attend a meeting temporarily, you forgot to log out. When the meeting is over, it was time to go home, so you left the office.
The next day, when you go back to work, you realize that you have not completed your purchase, so you go back to Zhuo Yue. Then, Zhuo Yue "remembers" that you are certified and said hello to you through your name, we still provide you with personalized Book recommendations, for excellence, subject. isremembered () returns true.
But what happens when you want to access the credit card information of your account to complete the book purchase? Although excellence "remembers" You (isremembered () = true), it cannot guarantee that you are You (maybe a colleague who is using your computer ).
Therefore, before you perform sensitive operations such as using credit card information, you are forced to log on to ensure that they guarantee your identity. After you log on, your identity has been verified, for excellence, isauthenticated () returns true.
This type of scenario often occurs, so Shiro has added this function and you can use it in your program. Whether to use isremembered () or isauthenticated () to customize your views and workflows depends entirely on you, But Shiro maintains this state basis in case you may need it.
Log out
The opposite of authentication is to release all known identity information. When the subject and the program no longer interact, you can call subject. logout () to discard all identity information.
Currentuser. logout (); // removes all identifying information and invalidates their session too.
When you call logout, any existing session will become unavailable and all the identity information will disappear (for example, the rememberme cookie information will also be deleted in web programs ).
When a Subject exits, the subject is renamed anonymous again. For web programs, you can log on again if necessary.
Pay attention to Web Applications
Because cookies are often used to remember identity information in web programs, and cookies can only be deleted when response is submitted, it is strongly required to call subject for end users. after logout (), the user is immediately directed to a new page to ensure that any security-related cookies are deleted as scheduled. This is the limitation of HTTP cookies, not Shiro.
Authentication Sequence
Until now, we only see how to verify a suject in the program code. Now let's take a look at what happens inside Shiro when a verification occurs.
We still use the architecture diagram we have seen in the architecture section. Only Authentication-related components on the left are highlighted. Each number represents one step in authentication:
Step 2:The program code calls the subject. login method to pass the user's identity and proof to the constructor of the authenticationtoken instance.
Step 2:A subject instance, usually a delegatingsubject (or its subclass), transfers this token to the program's securitymanager by calling securitymanager. login (token.
Step 2:Securitymanager, basic "security umbrella" component, obtains the token and calls authenticator. authenticate (token) simply transfers it to its internal authenticator instance. In most cases, it is a modularrealmauthenticator instance that supports coordinating one or more realm instances during verification. Modularrealmauthenticator essentially provides an example of the PAM type for Apache Shiro (each realm in Pam terminology is called a "MODULE.
Step 2:If the program is configured with multiple realm instances, the modularrealmauthenticator instance uses the configured authenticationstrategy to start a multi-realm authentication attempt. Throughout the realm verification call process, authenticationstrategy (Security Policy) is called to respond to each realm result. We will discuss authenticationstrategies later.
Note: single realm Program
If only one realm is configured, it is called directly -- authenticationstrategy is not required in a single realm program.
Step 2: The realm of each configuration is verified to see whether it supports the submitted authenticationtoken. If yes, the getauthenticationinfo method of the realm is called along with the submitted card, the getauthenticationinfo method provides an independent verification attempt for a specific realm. We will discuss the realm verification behavior later.
Authenticator
As mentioned previously, Shiro securitymanager implementations uses a modularrealmauthenticator instance by default. modularrealmauthenticator also supports single realm and multi-realm.
In a single realm program, modularrealmauthenticator runs a separate realm directly. If two or more realm instances are configured, The authenticationstrategy instance is used to coordinate how to perform verification, we will discuss authenticationstrategy in the following chapter.
If you want to use a custom authenticator to configure securitymanager, you can do this in Shiro. ini, for example:
[Main]
...
Authenticator = com. Foo. Bar. customauthenticator
Securitymanager. authenticator = $ authenticator
Although in practice, modularrealmauthenticator is applicable to most requirements.
Authenticationstrategy
When two or more realm are defined in a program, modularrealmauthenticator uses an internal authenticationstrategy component to determine whether a verification is successful.
For example, if a realm instance successfully verifies an authenticationtoken, but all others fail, is this attempt considered successful? Is it true that all realm verification is successful? Or if a realm is successfully verified, is there any need to discuss other realm? Authenticationstrategy makes appropriate decisions based on program requirements.
Authenticationstrategy is a stateless component that is used four times throughout the verification process (the State will be passed as a method parameter when necessary State is required in these four activities)
1. Before any realms is executed;
2. Before calling the getauthenticationinfo method of a realm instance;
3. After calling the getauthenticationinfo method of a realm instance;
4. After all realm instances are executed.
Authenticationstrategy also has the responsibility to collect results from each successful realm and "bind" them to a separate authenticationinfo. This authenticationinfo instance is returned by the authenticator instance, shiro uses it to present the final identity (principals) of a subject ).
Subject Identity "View )"
If you use more than one realm in a program to obtain account data from multiple data sources, it is the responsibility of authenticationstrategy to display the final "merged" of the subject identity that the program can see.
Shiro has three specific authenticationstrategy implementations:
Atleastonesuccessfulstrategy: if one or more realm instances are successfully verified, all attempts are considered successful. If none of them are successfully verified, the attempt fails;
Firstsuccessfulstrategy: only the information returned from the first successfully verified realm will be used, and future realm will be ignored. If no verification succeeds, this attempt fails.
Successfulstrategy: All configured realm instances are successfully verified in all attempts. If one attempt fails, this attempt fails.
Modularrealmauthenticator uses atleastonesuccessfulstrategy by default. This is also the most common policy. However, you can configure different policies you want.
Shiro. ini
[Main]
...
Authcstrategy = org. Apache. Shiro. authc. Pam. firstsuccessfulstrategy
Securitymanager. authenticator. authenticationstrategy = $ authcstrategy
...
Custom authenticationstrategy
If you want to create your own authenticationstrategy
You can use org. Apache. Shiro. authc. Pam. abstractauthenticationstrategy as the starting point. The abstractauthenticationstrategy class automatically implements 'bundling '/aggregation to collect the results from each realm to an authenticationinfo instance.
Realm verification sequence
It is very important that the modularrealmauthenticator that interacts with realm is executed in the iteration order.
Modularrealmauthenticator can access the realm instance configured for securitymanager. When a verification attempt is made, it traverses the collection and supports the getauthenticationinfo method of realm for each realm processed by the submitted authenticationtoken.
Implicit order
When using the shiroini configuration file, you can configure realm in the order you want it to process authenticationtoken, for example, in Shiro. in Ni, realm will be executed in the order defined in the INI file.
Blahrealm = com. Company. Blah. realm
...
Foorealm = com. Company. Foo. realm
...
Barrealm = com. Company. Another. realm
These three realm are configured on securitymanager. During a verification process, blahrealm, foorealm, and barrealm are executed sequentially.
This basically has the same effect as defining the following statement:
Securitymanager. Realms = $ blahrealm, $ foorealm, $ barrealm
In this way, you do not need to set the realm sequence of securitymanager. Each defined realm is automatically added to the realms attribute.
Clear order
If you want to clearly define the sequence of realm execution, regardless of how they are defined, you can set the realms attribute of securitymanager, for example, using the realm defined above, but you want the final execution of blahrealm instead of the first one:
Blahrealm = com. Company. Blah. realm
...
Foorealm = com. Company. Foo. realm
...
Barrealm = com. Company. Another. realm
Securitymanager. Realms = $ foorealm, $ barrealm, $ blahrealm
...
Clarify realm inclusion
When you explicitly configure securitymanager. for realms attributes, only the referenced realm will be configured for securitymanager. That is to say, you may have defined five realm in ini, but actually only three are used, if only three realm attributes are referenced, This is different from the implicit realm order. In that case, all valid realm instances will be used.
Realm Verification
This chapter describes the main workflow of Shiro when a verification attempt occurs, and the workflow generated within realm used during the verification process (such as step 1 mentioned above) the realm authentication section will be discussed in the realm chapter.
Add document handles
We hope this document will help you use Apache Shiro for work. The community is constantly improving and expanding the document. If you want to help Shiro projects, please consider correcting, expanding, or adding documents where you think it is necessary. any bit of help you provide will expand the community and promote Shiro.
The easiest way to provide your documents is to send it to a user forum (http://shiro-user.582556.n2.nabble.com/) or a list of emails (http://shiro.apache.org/mailing-lists.html)
Address: http://shiro.apache.org/authentication.html