一、导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
二、自定义Realm类继承AuthorizingRealm类
实现里面的两个方法,一个是认证方法,一个是授权方法,在认证方法中只需要做用户名的校验,密码校验会在父类中自动完成
package com.szhedu.realm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class CustomerRealm extends AuthorizingRealm {
//授权方法
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证方法
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//底层会在这里被调用实现认证
//根据token获取用户名
Object principal = authenticationToken.getPrincipal();
//模拟:查询数据库得到用户名
if ("zihao".equals(principal)){
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal, "123456", this.getName());
return authenticationInfo;
}
return null;
}
}
三、使用自定义Reaml认证
package com.szhedu;
import com.szhedu.realm.CustomerRealm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
public class TestCustomerRealmAuthenticator {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2.安全管理器设置realm
securityManager.setRealm(new CustomerRealm());
//3.SeculityUtils给全局安全工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//4.获取主体
Subject subject = SecurityUtils.getSubject();
//5.创建token
UsernamePasswordToken token = new UsernamePasswordToken("zihao", "123456");
//6.校验
try {
subject.login(token);
System.out.println(subject.isAuthenticated());
} catch (AuthenticationException e) {
throw new RuntimeException(e);
}
}
}
四、Shiro中使用MD5加随机盐实现认证
package com.szhedu;
import com.szhedu.realm.CustomerMD5Realm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
public class TestCustomerMD5RealmAuthenicator {
public static void main(String[] args) {
//1.创建安全管理器
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//2.安全管理器设置realm
CustomerMD5Realm realm = new CustomerMD5Realm();
//todo 3.设置realm使用hash凭证匹配器
//这里,就会先对用户输入的密码进行MD5加密,然后再用加密后的密码去和数据库中的密码做equals判断
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
//使用的算法
hashedCredentialsMatcher.setHashAlgorithmName("md5");
//散列的次数
hashedCredentialsMatcher.setHashIterations(1024);
realm.setCredentialsMatcher(hashedCredentialsMatcher);
securityManager.setRealm(realm);
//4.SeculityUtils给全局安全工具类设置安全管理器
SecurityUtils.setSecurityManager(securityManager);
//5.获取主体
Subject subject = SecurityUtils.getSubject();
//用户登陆时密码为123
UsernamePasswordToken token = new UsernamePasswordToken("zihao", "123");
try {
subject.login(token);
System.out.println("登录成功");
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误");
}catch (IncorrectCredentialsException e){
e.printStackTrace();
System.out.println("密码错误");
}
}
}
Realm类中:
package com.szhedu.realm;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
public class CustomerMD5Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal = (String) authenticationToken.getPrincipal();
/*
1.正常只用MD5加密
if ("zihao".equals(principal)){
//todo 这里,查询数据库的用户名和密码,注意数据库中密码是MD5加密的
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
principal,
"202cb962ac59075b964b07152d234b70",
this.getName());
return authenticationInfo;
}
*/
if ("zihao".equals(principal)){
//todo 参数1:用户名 参数2:数据库MD5+盐后的密码 参数3:注册时的随机盐 参数4:realm的名字
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
principal,
"0d4ca73f2f670d331c2d892e7e403197",
//这里只要返回了盐,用户输入的密码在底层就会拼接这里的盐,然后再做MD5
ByteSource.Util.bytes("szh*O@x"),
this.getName());
return authenticationInfo;
}
return null;
}
}