2.1一样先导包
<!--使用shiro需要先导包-->
<dependencies>
<!--shiro的核心包-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<!--日志包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--测试包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
</dependencies>
2.2准备自定义Realm
- 写一个Realm,继承
AuthorizingRealm
- 提供了两个方法,一个是授权
doGetAuthorizationInfo
,一个是身份认证 doGetAuthenticationInfo
(准备个MyRealm.java文件,填写如下内容 )
public class MyRealm extends AuthorizingRealm {
//授权认证功能就写在这里面
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取授权对象
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//从getRoles()方法中获取角色并放且放到授权对象中,getRoles()方法在下面
Set<String> roles = getRoles();
authorizationInfo.setRoles(roles);
//从getPerms()方法中获取权限并放且放到授权对象中,getPerms()方法在下面
Set<String> perms = getPerms();
authorizationInfo.setStringPermissions(perms);
return authorizationInfo;
}
/**
* 假设这里获取到当前用户的角色
*/
private Set<String> getRoles(){
Set<String> roles = new HashSet<>();
roles.add("admin");
roles.add("it");
return roles;
}
/**
* 假设这里获取到当前用户的权限
*/
private Set<String> getPerms(){
Set<String> perms = new HashSet<>();
perms.add("employee:index");
return perms;
}
/**
* 记住:如果这个方法返回null,就代表是用户名错误,shiro就会抛出:UnknownAccountException
*/
//身份认证(登录)就写在这里面
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.拿到令牌(UsernamePasswordToken)
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
//2.拿到用户名,判断这个用户是否存在
// 2.1 拿到传过来的用户名
String username = token.getUsername();
// 2.2 根据用户名从getUsers()方法中拿到密码,getUsers()方法在下面
String password = this.getUsers(username);
// 2.3 如果没有拿到密码(没有通过用户名拿到相应的用户->用户不存在)
if(password==null){
return null;
}
//记住:我们只在正常完成这里的功能,shiro会判断密码是否正确
//3.返回 AuthenticationInfo这个对象
/**
* 咱们创建对象需要传的参数:SimpleAuthenticatinInof(4个参数顺序解释)
* Object principal:主体(可以乱写) -> 登录成功后,你想把哪一个对象存下来
* Object credentials:凭证(就是密码) -> 数据库中的密码
* credentials(密码)Salt:盐值
* String realmName : realm的名称(可以乱写)
*/
//拿到咱们的盐值对象(ByteSource)
ByteSource salt = ByteSource.Util.bytes("itsource");
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,"myRealm");
return authenticationInfo;
}
/**
* 假设这里是根据用户名进行的查询
* MD5:e10adc3949ba59abbe56e057f20f883e
* MD5+10次:4a95737b032e98a50c056c41f2fa9ec6
* MD5+10次+itsource:831d092d59f6e305ebcfa77e05135eac
*/
public String getUsers(String username){
if("admin".equals(username)){
return "831d092d59f6e305ebcfa77e05135eac";
}else if("zhang".equals(username)){
return "123";
}
return null;
}
}
2.3测试自定义Realm(一定得有import org.junit.Test;才能测试)
@Test
public void testMyRealm() throws Exception{
//一.创建一个SecurityManager对象
// 1.创建realm对象
MyRealm myRealm = new MyRealm();
// 2.创建SecurityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager(myRealm);
//②.相当于把SecurityManager放到了当前上下文
SecurityUtils.setSecurityManager(securityManager);
//③.拿到当前用户
Subject subject = SecurityUtils.getSubject();
//Hashed(哈希)Credentials(认证)Matcher(匹配器)
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
//设置哈希算法
matcher.setHashAlgorithmName("MD5");
//设置迭代次数
matcher.setHashIterations(10);
//把匹配器交给shiro
myRealm.setCredentialsMatcher(matcher);
System.out.println("用户是否登录:"+subject.isAuthenticated());
//④.如果没有登录,让他登录
if(!subject.isAuthenticated()){
try {
UsernamePasswordToken token = new UsernamePasswordToken("admin","123456");
subject.login(token);
} catch (UnknownAccountException e) {
e.printStackTrace();
System.out.println("用户名错误");
} catch (IncorrectCredentialsException e) {
e.printStackTrace();
System.out.println("密码错误");
} catch (AuthenticationException e) {
e.printStackTrace();
System.out.println("神迷错误");
}
}
System.out.println("用户是否登录:"+subject.isAuthenticated());
System.out.println("是否是admin角色:"+subject.hasRole("admin"));
System.out.println("是否是hr角色:"+subject.hasRole("hr"));
System.out.println("是否有employee:index权限:"+subject.isPermitted("employee:index"));
System.out.println("是否有employee:save权限:"+subject.isPermitted("employee:save"));
System.out.println("是否有department:index权限:"+subject.isPermitted("department:index"));
}