certification
Identity authentication is the process of determining whether a user is a legitimate user. The most common simple authentication method is that the system checks whether the user name and password entered by the user are consistent with the user name and password stored in the system to determine whether the user identity is correct.
Key object for Shiro certification
- Subjects can be users, applications, and so on accessing the system. Anything that needs to be authenticated is called a principal.
- Principal: The identity information used by the Subject for identity authentication. The identity must be unique. For example, the user name, mobile phone number, and email address. A Principal can have multiple identities, but there must be one Primary Principal.
- Credential: security information, such as passwords and certificates, that only the subject knows.
Shiro certification process
The user authenticates with identity and credential information (typically a username and password), and Shiro packages the information we provide into a Token, which is then sent to Shiro’s Security Manager for verification. The verification process is as follows: The Security Manager calls the Authenticator, and the Authenticator calls Pluggable Realms to get the raw data. Then the raw data is matched with the user-provided information. If the data is consistent, the authentication succeeds.
The Demo Shrio certification
-
Introduce dependencies in POM.xml
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.5.3</version> </dependency> Copy the code
-
Create the shiro.ini file in the Resources directory
[users] john=123 peter=12345 Copy the code
Ini is a configuration file in Shiro that can write system permission data in the INI file when there is no connection to the database.
-
Demo
public static void main(String[] args) { DefaultSecurityManager is a concrete implementation of the SecurityManager interface DefaultSecurityManager securityManager = new DefaultSecurityManager(); // Set the security manager to Realm for identity and credential data securityManager.setRealm(new IniRealm("classpath:shiro.ini")); // Global security tool class provided by Shiro SecurityUtils Security tool Sets the security manager for authentication SecurityUtils.setSecurityManager(securityManager); // Key object Subject Subject of the current login Subject subject = SecurityUtils.getSubject(); // Create a token with the identity information as username UsernamePasswordToken token = new UsernamePasswordToken("john"."123"); try { // User authentication If the authentication succeeds, no exception will be thrown subject.login(token); // Obtain the authentication status. True indicates that the authentication succeeds. False indicates that the authentication fails System.out.println("Certification Status:" + subject.isAuthenticated()); } catch (UnknownAccountException e) { The user name does not exist e.printStackTrace(); } catch (IncorrectCredentialsException e) { // Authentication failed. The password is incorrecte.printStackTrace(); }}Copy the code
Shiro certified source code
The Demo uses Shiro’s lniRealm. IniRealm reads user information from the INI configuration file. In most cases, you need to read user information from the system database, so you need to customize the Realm.
Shiro provides the following system Realm:
Realms designed for authentication are as follows:
The SimpleAccountRealm class is the low-level authentication and authorization operations that Shiro does by default, with the doGetAuthenticationInfo method handling authentication and the doGetAuthorizationInfo method handling authorization.
public class SimpleAccountRealm extends AuthorizingRealm {...// Authentication processing
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
SimpleAccount account = getUser(upToken.getUsername());
if(account ! =null) {
if (account.isLocked()) {
throw new LockedAccountException("Account [" + account + "] is locked.");
}
if (account.isCredentialsExpired()) {
String msg = "The credentials for account [" + account + "] are expired";
throw newExpiredCredentialsException(msg); }}return account;
}
// Authorization processing
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = getUsername(principals);
USERS_LOCK.readLock().lock();
try {
return this.users.get(username);
} finally{ USERS_LOCK.readLock().unlock(); }}}Copy the code
The doGetAuthenticationInfo method defined in the SimpleAccountRealm class only handles authentication of identity information (user name). Authentication of passwords is handled automatically by Shiro.
Custom Authentication
If we want to change the mode of reading data from the INI configuration file to reading data from the database, we must define a class that inherits AuthorizingRealm and rewrite the doGetAuthenticationInfo method.
public class UserRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
// Modify the authentication processing method
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// Get the identity information
String username = (String) token.getPrincipal();
// Read data from the database for authentication and password authentication
if ("john".equals(username)) {
// Parameter 1: user name parameter 2: password parameter 3: current Realm name
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, "123".this.getName());
// Successful authentication returns SimpleAuthenticationInfo
return simpleAuthenticationInfo;
}
return null; }}Copy the code
Then modify the injected Realm
public static void main(String[] args) {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
// Inject custom realms
UserRealm userRealm = new UserRealm();
securityManager.setRealm(userRealm);
securityManager.setRealm(new IniRealm("classpath:shiro.ini"));
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("john"."123");
try {
subject.login(token);
System.out.println("Certification Status:" + subject.isAuthenticated());
} catch (UnknownAccountException e) {
e.printStackTrace();
} catch(IncorrectCredentialsException e) { e.printStackTrace(); }}Copy the code