Shiro, apacheshiro

Source: Internet
Author: User

Shiro, apacheshiro

Authentication is the most basic work of Shiro!

 

Start from the code, and then study it slowly. The dependecies I added are as follows:

<!-- shiro --><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-web</artifactId>    <version>${shiro.version}</version></dependency>

 

Create shiro. ini in the Resource Directory. The file content is:

[users]king=t;stmdtkg


Write a main method: package pac. testcase. shiro;

Import org. apache. shiro. securityUtils; import org. apache. shiro. authc. excessiveAttemptsException; import org. apache. shiro. authc. incorrectCredentialsException; import org. apache. shiro. authc. lockedAccountException; import org. apache. shiro. authc. unknownAccountException; import org. apache. shiro. authc. usernamePasswordToken; import org. apache. shiro. config. iniSecurityManagerFactory; import org. apache. shiro. mgt. se CurityManager; import org. apache. shiro. subject. subject; import org. apache. shiro. util. factory; public class TestAuthen {public static void main (String [] args) {Factory <SecurityManager> factory = new IniSecurityManagerFactory (); SecurityManager manager = factory. getInstance (); SecurityUtils. setSecurityManager (manager); UsernamePasswordToken token = new UsernamePasswordToken ("king", "t; stmdtkg"); toke N. setRememberMe (true); Subject currentUser = SecurityUtils. getSubject (); try {currentUser. login (token);} catch (UnknownAccountException e) {System. out. println ("who are you? ");} Catch (IncorrectCredentialsException e) {System. out. println (" Incorrect password !! ");} Catch (LockedAccountException e) {System. out. println (" this account is unavailable ~ ");} Catch (ExcessiveAttemptsException e) {System. out. println (" don't try again !! ") ;}Currentuser. logout ();}}

 

The code is very understandable. If the configuration file is not specified for IniSecurityManagerFactory

DEFAULT_INI_RESOURCE_PATH = "classpath:shiro.ini"。


In addition, SecurityUtils. setSecurityManager (manager) is a global setting. This method is rarely used in development.

In addition, Shiro provides a variety of exceptions. We can respond to different prompts based on different catch methods.

 

Two important concepts of Identity Authentication need to be explained:

  • Principals: the unique identifier of a Subject. It can be anything, such as the user name or email address.
  • Credentials: Credentials, a credential used to prove your identity. It can be simply understood as a password.

In the naming of some classes and methods, these words are not too unfamiliar.

 

Record the specific steps for identity authentication, and summarize them in five steps:

Step 1.

Call the login method by using the token object that represents the user identity and credential as a parameter.

 

Step 2.

In the above Code, the Subject object is actually a DelegatingSubject object used to delegate (delegate) tasks to call login (token) to delegate the verification task to SecurityManager. SecurityManager call

Subject login(Subject subject, AuthenticationToken authenticationToken)

Here is where verification really starts.

 

Step 3.

SecurityManager, as a 'umbrebala' component (is this metaphor very popular...), receives tokens and Delegates tasks to internalAuthenticator(Ps: SecurityManager extends Authenticator, Authorizer, SessionManager) and call

public AuthenticationInfo authenticate(AuthenticationToken authenticationToken)        throws AuthenticationException;

Generally, the authenticator is token, which can communicate with multiple realm during verification (ModularRealmAuthenticator implements AuthenticationInfo doAuthenticate (AuthenticationToken), and the upper-level AbstractAuthenticator implements authenticate (token) to call doAuthenticate (token )).

 

Step 4.

If multiple Realm instances are configured, ModularRealmAuthenticator uses the configured Authentication Policy (AuthenticationStrategy) for multi-Realm authentication.

The verification policy interacts with the result of each Realm.

If only one Realm is configured, the authentication policy is meaningless.

 

Step 5.

Call Realm's boolean supports (AuthenticationToken token) to check whether Realm supports the submitted token.

If Realm supports submitted tokens, the tokens are used as parameters and called:

AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException;

Response specific authentication information (AuthenticationInfo) based on different tokens ).

When an application is configured with multiple Realm, ModularRealmAuthenticator defines the authentication policy through its internal AuthenticationStrategy (it seems that the name is really great ...).

For example, if a Realm successfully verifies a token and all other Realm instances fail, how can we determine whether the verification succeeds or fails?

Is it successful after all passes? Or is it okay to pass one of them? Or is it necessary to continue to consider other issues after a specific number of passes?

 

 

Next, try to use the code to experienceMulti-RealmAndAuthenticationStrategy

Step 1.

Implement org. apache. shiro. realm. Realm to customize several Realm.

In the getAuthenticationInfo method, the verification information is directly returned, and the validation policy does not take effect. Therefore, I throw an exception in a Realm.

package pac.testcase.shiro.realm;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.realm.Realm;public class MyRealm1 implements Realm {    public String getName() {        return this.getClass().getName();    }    public boolean supports(AuthenticationToken token) {        return true;    }    public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token)            throws AuthenticationException {        if(!new String((char[])token.getCredentials()).equals("t;stmdtkg"))            throw new IncorrectCredentialsException();        return new SimpleAuthenticationInfo(token.getPrincipal(),token.getCredentials(),this.getName());    }}
Step 2.

Continue to use the code at the beginning of this article and configure several customized Realm to shiro. ini.

realm0=pac.testcase.shiro.realm.MyRealm0realm1=pac.testcase.shiro.realm.MyRealm1
Step 3.

Configure the verification policy in shiro. ini.

realm0=pac.testcase.shiro.realm.MyRealm0realm1=pac.testcase.shiro.realm.MyRealm1authcStrategy = org.apache.shiro.authc.pam.AllSuccessfulStrategysecurityManager.authenticator.authenticationStrategy = $authcStrategy
Step 4.

Run the program and output "Incorrect password !! "

AuthenticationStrategy isStatelessAuthenticationStrategy interacts with each other four times when processing a verification request.

They are:

  • Before any Realm is executed.
  • Before each Realm's getAuthenticationInfo method is called.
  • After each Realm's getAuthenticationInfo method is called.
  • After all Realm instances are executed.

 

In addition, it is also the work of AuthenticationStrategy to gather results from all successful Realm and bind them to an AuthenticationInfo.

The verification information aggregated at the end is the sign used by Shiro to represent the Subject, that is, the so-called Principal.

This is embodied in org. apache. shiro. authc. pam. ModularRealmAuthenticator:

protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {    AuthenticationStrategy strategy = getAuthenticationStrategy();    AuthenticationInfo aggregate = strategy.beforeAllAttempts(realms, token);    if (log.isTraceEnabled()) {        log.trace("Iterating through {} realms for PAM authentication", realms.size());    }    for (Realm realm : realms) {        aggregate = strategy.beforeAttempt(realm, token, aggregate);        if (realm.supports(token)) {            log.trace("Attempting to authenticate token [{}] using realm [{}]", token, realm);            AuthenticationInfo info = null;            Throwable t = null;            try {                info = realm.getAuthenticationInfo(token);            } catch (Throwable throwable) {                t = throwable;                if (log.isDebugEnabled()) {                    String msg = "Realm [" + realm + "] threw an exception during a multi-realm authentication attempt:";                    log.debug(msg, t);                }            }            aggregate = strategy.afterAttempt(realm, token, info, aggregate, t);        } else {            log.debug("Realm [{}] does not support token {}.  Skipping realm.", realm, token);        }    }    aggregate = strategy.afterAllAttempts(token, aggregate);    return aggregate;}

 

 

Shiro provides three AuthenticationStrategy implementations by default:

  • AtLeastOneSuccessfulStrategy: if one of them passes, the operation succeeds.
  • FirstSuccessfulStrategy: one of them passes successfully, but only the verification information provided by the first passed Realm is returned.
  • AllSuccessfulStrategy: All Realm configurations in the application must pass.

 

ModularRealmAuthenticator uses AtLeastOneSuccessfulStrategy by default. If you want to use other authentication policies, you must configure them by yourself.

It should be noted that ModularRealmAuthenticator interacts with each Realm in a certain order.

ModularRealmAuthenticator access is configured on the Realm of SecurityManager.

When processing a verification request, it iterates the Realm set and calls all Realm that support the current token.

If you use the ini configuration, it will be executed according to the configuration order.

If you want to display the order in which Realm is defined, set it in the desired order in the securityManager attribute.

For example:

securityManager.realms=$myRealm2,$myRealm1

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.