Shiro
实际进行权限信息验证的是我们的 Realm,Shiro 框架内部默认实现外,就是自定义Realm,重写doGetAuthorizationInfo和doGetAuthenticationInfo
根据从主体传过来的用户名,从数据源取password, roles, permissions进行比对。
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principalCollection) {
// 1.从主体传过来的认证信息中,获得用户名
String userName = (String) principalCollection.getPrimaryPrincipal();
// 2.从数据库获取角色和权限数据
Set<String> roles = getRolesByUserName(userName);
Set<String> permissions = getPermissionsByUserName(userName);
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
simpleAuthorizationInfo.setStringPermissions(permissions);
simpleAuthorizationInfo.setRoles(roles);
return simpleAuthorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authenticationToken) throws AuthenticationException {
// 1.从主体传过来的认证信息中,获得用户名
String userName = (String) authenticationToken.getPrincipal();
// 2.通过用户名到数据库中获取凭证
String password = getPasswordByUserName(userName);
if (password == null) {
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
userName, password, "myRealm"
);
return authenticationInfo;
}
}
public class MyRealmTest {
@Test
public void loginTest() {
MyRealm myRealm = new MyRealm(); // 实现自己的 Realm 实例
// 1.构建SecurityManager环境
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
defaultSecurityManager.setRealm(myRealm);
// 2.主体提交认证请求
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("yanjing", "123456");
subject.login(token); // 登录
// subject.isAuthenticated()方法返回一个boolean值,用于判断用户是否认证成功
System.out.println("isAuthenticated:" + subject.isAuthenticated()); // 输出true
// 判断subject是否具有admin和user两个角色权限,如没有则会报错
subject.checkRoles("admin", "user");
subject.checkRole("admin");
// 判断subject是否具有user:add和user:delete权限
subject.checkPermissions("user:delete", "user:add");
subject.checkPermissions("user:delete");
}
}
加密解密
MD5, sha256, sha512, 加盐,增加Hash迭代次数
public class EncryptUtil {
public static void main(String[] args) {
encrypt("123");
}
public static String encrypt(String password) {
String salt = new SecureRandomNumberGenerator().nextBytes().toString();
int times = 2;
String alogrithm = "md5"; // 加密算法
String encryptedPassword = new SimpleHash(alogrithm, password, salt, times).toString();
System.out.printf("原始密码是 %s , 盐是: %s, 运算次数是: %d, 运算出来的密文是:%s ",
password, salt, times, encryptedPassword);
return encryptedPassword;
}
}
cryptojs 配合后端 前端vue使用crypto.js加密Java后端解密
java.net.URLDecoder