为何要自定义Realm?
Shiro框架中并没有提供一个以SpringDataJpa来实现访问数据的这样一个Realm,所以我们必须自定义一个Realm
如何自定义?
Realm是Shiro框架中的一个接口,那么我们要自定义Realm的话,就只需要自定义一个类去实现Realm接口就行了。
如果直接实现Realm接口的话,这个自定义的Realm只能用来做登录,无法用来做权限认证功能。
将我们自定义的JpaRealm类继承AuthorizingRealm类,就可以制作登录和权限认证的功能了
public class JpaRealm extends AuthorizingRealm {
/**
* 授权方法
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("授权");
//获取当前登录用户对象
Employee employee = (Employee)SecurityUtils.getSubject().getPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
//通过该用户去查询他的权限
Set<String> permissions = this.findPermissionsByEmployeeId(employee.getId());
//授权
authorizationInfo.setStringPermissions(permissions);
return authorizationInfo;
}
private Set<String> findPermissionsByEmployeeId(Long id) {
Set<String> permissions = new HashSet<>();
permissions.add("employee:index");
permissions.add("employee:page");
return permissions;
}
/**
* 身份认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//类型强转
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//获取用户名
String username = token.getUsername();
Employee employee = this.findByUsername(username);
if(employee != null){
//ByteSource credentialsSalt 盐值
ByteSource salt = ByteSource.Util.bytes("abcdefg");
return new SimpleAuthenticationInfo(employee,employee.getPassword(),salt,"JpaRealm");
}
return null;
}
private Employee findByUsername(String username) {
if("admin".equals(username)){
Employee employee = new Employee();
employee.setUsername("admin");
employee.setPassword("09f81be23578bdfe69565849199acaef");
return employee;
}
return null;
}
}
测试
public class _09_RealmTest {
/**
* 登录测试
* @throws Exception
*/
@Test
public void test() throws Exception{
//创securityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//创建自定义的JpaRealm对象
JpaRealm jpaRealm = new JpaRealm();
//将其设置到securityManager对象属性上
securityManager.setRealm(jpaRealm);
SecurityUtils.setSecurityManager(securityManager);
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//判断是否登录
System.out.println(subject.isAuthenticated());
try {
if (!subject.isAuthenticated()) {
//未登录的话就登录
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 (Exception e) {
e.printStackTrace();
System.out.println("系统繁忙,连接超时");
}
System.out.println(subject.isAuthenticated());
if (subject.isAuthenticated()) ;
{
//登出
subject.logout();
}
//判断是否登录
System.out.println(subject.isAuthenticated());
}
/**
* 权限测试
* @throws Exception
*/
@Test
public void test02() throws Exception{
//创securityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//创建自定义的JpaRealm对象
JpaRealm jpaRealm = new JpaRealm();
//将其设置到securityManager对象属性上
securityManager.setRealm(jpaRealm);
SecurityUtils.setSecurityManager(securityManager);
//获取当前用户
Subject subject = SecurityUtils.getSubject();
//判断是否登录
System.out.println(subject.isAuthenticated());
try {
if (!subject.isAuthenticated()) {
//未登录的话就登录
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 (Exception e) {
e.printStackTrace();
System.out.println("系统繁忙,连接超时");
}
System.out.println(subject.isAuthenticated());
//判断该用户的权限
System.out.println("save:"+subject.isPermitted("employee:save"));
System.out.println("page:"+subject.isPermitted("employee:page"));
System.out.println("index:"+subject.isPermitted("employee:index"));
if (subject.isAuthenticated()) ;
{
//登出
subject.logout();
}
//判断是否登录
System.out.println(subject.isAuthenticated());
}
}