Foreword
This chapter explains shiro custom realm and its encryption algorithm
method
1. Concept
By the previous lecture, I have brought the concepts of Custom Realm. So why do the custom realm? Obvious, users table we created in the database and its field is limited to shiro own jdbcRealm, so under normal circumstances we need to use their own table, follow must use a custom realm.
Further, in the user table, the value of the password field is a sensitive exists. We need to take some encryption algorithms ensure the preservation of the complexity of the password value in the database. So common encryption algorithm is md5, sha and so on. By traditional encryption algorithm "salt" and increase the number of iterations, can effectively ensure password security.
2. Custom realm of realization
First observed in the realm of inheritance shiro:
We can easily find our JdbcRealm inherited AuthorizingRealm, the same token, our custom realm also need to extend this class!
Preliminary write code as follows:
package cn.edu.ccut.test;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:cn.edu.ccut.test
* @Version 1.0
**/
public class MyJdbcRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
return null;
}
}
We found that he had two methods need to be rewritten, is a certification method, a method is authorized, of course we first rewrite authentication method doGetAuthenticationInfo !
JdbcRealm by reading the source code, we can easily write custom realm is as follows:
package cn.edu.ccut.test;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:cn.edu.ccut.test
* @Version 1.0
**/
public class MyJdbcRealm extends AuthorizingRealm {
@Override
public String getName() {
return "MyJdbcRealm";
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
//假设通过username取出密码为1234,jdbc代码略
String password = "1234";
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password.toCharArray(), getName());
return info;
}
}
In shiro.ini file to configure a custom realm
[main]
dataSource = com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass = oracle.jdbc.driver.OracleDriver
dataSource.jdbcUrl = jdbc:oracle:thin:@localhost:1521:orcl
dataSource.user = scott
dataSource.password = tiger
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
myJdbcRealm = cn.edu.ccut.test.MyJdbcRealm
#iniRealm = cn.edu.ccut.test.MyRealm
# $相当于spring的依赖注入
jdbcRealm.dataSource = $dataSource
#authenticationStrategy = org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
#securityManager.authenticator.authenticationStrategy = $authenticationStrategy
securityManager.realms = $myJdbcRealm
So before I use it still test class, user name, password input is zhangsan / 1234, verified by!
Note: Custom realm, I omitted the process getPassword in the database, we can set the table according to their own preferences, can be acquired through knowledge of jdbc!
3.shiro encryption algorithm
1) encryption algorithm to explore shiro
In shiro, there is a cryptographic hash algorithms md5 and sha the
First, we write a simple example of the use of small shiroMd5Hash class encryption:
import org.apache.shiro.crypto.hash.Md5Hash;
import org.junit.Test;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:PACKAGE_NAME
* @Version 1.0
**/
public class PasTest {
@Test
public void testMd5(){
String password = "1111";
Md5Hash md5 = new Md5Hash(password);
System.out.println(password+"加密后的结果:"+md5.toString());
}
}
Results are as follows:
We went to the well-known website md5 crack up crack (decrypt) at:
Obviously, this is not safe. . . . .
This time we need salt :
import org.apache.shiro.crypto.hash.Md5Hash;
import org.junit.Test;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:PACKAGE_NAME
* @Version 1.0
**/
public class PasTest {
@Test
public void testMd5(){
String password = "1111";
//加盐,设置颜值为==》open
String password_salt = "open";
Md5Hash md5 = new Md5Hash(password,password_salt);
System.out.println(password+"加密后的结果:"+md5.toString());
}
}
Results are as follows:
Over, this is not safe. . .
All right, we have a big move! Plus the number of iterations, which is continuing encryption.
import org.apache.shiro.crypto.hash.Md5Hash;
import org.junit.Test;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:PACKAGE_NAME
* @Version 1.0
**/
public class PasTest {
@Test
public void testMd5(){
String password = "1111";
//加盐,设置颜值为==》open
String password_salt = "open";
//迭代次数
int hashIterations = 2;
Md5Hash md5 = new Md5Hash(password,password_salt,hashIterations);
System.out.println(password+"加密后的结果:"+md5.toString());
}
}
Results are as follows:
md5 decryption website effect is as follows:
I do not know Editor's Note, we do not dare to ask ah. But still better than the previous security.
2) realm of using an encryption algorithm
We talked about before the custom realm into the following:
package cn.edu.ccut.test;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
/**
* @Auther:jwang
* @Date:2019/5/11
* @Description:cn.edu.ccut.test
* @Version 1.0
**/
public class MyJdbcRealm extends AuthorizingRealm {
@Override
public String getName() {
return "MyJdbcRealm";
}
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
//假设通过username取出密码为85b768bc6ac28bd054c7cd670046c706(1234加密后),jdbc代码略
String password = "85b768bc6ac28bd054c7cd670046c706";
//假设通过username取出颜值为open
String password_salt = "open";
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username, password.toCharArray(), ByteSource.Util.bytes(password_salt), getName());
return info;
}
}
So what we need to tell realm credentials matcher, that allowed how to decrypt. .
We source and found that there is a realm in property credentialsMatcher is evidence matcher
Since we are using the md5 encryption algorithm, so use md5 certificate matcher:
Shiro configuration file as follows:
[main]
dataSource = com.mchange.v2.c3p0.ComboPooledDataSource
dataSource.driverClass = oracle.jdbc.driver.OracleDriver
dataSource.jdbcUrl = jdbc:oracle:thin:@localhost:1521:orcl
dataSource.user = scott
dataSource.password = tiger
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
myJdbcRealm = cn.edu.ccut.test.MyJdbcRealm
#配置凭证匹配器
md5CredentialsMatcher = org.apache.shiro.authc.credential.Md5CredentialsMatcher
#迭代次数
md5CredentialsMatcher.hashIterations = 2
myJdbcRealm.credentialsMatcher = $md5CredentialsMatcher
#iniRealm = cn.edu.ccut.test.MyRealm
# $相当于spring的依赖注入
jdbcRealm.dataSource = $dataSource
#authenticationStrategy = org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
#securityManager.authenticator.authenticationStrategy = $authenticationStrategy
securityManager.realms = $myJdbcRealm
Note: no need to change the configuration file to configure color value, color values are available in the database, the database table structure before recall settings:
This time, you will understand the meaning of password_salt the field!
The above operation result of the login authentication code as follows: