自定义realm:
AutuRealm.java
public class AuthRealm extends AuthorizingRealm{ @Autowired private UserService userService; /** * 为用户授权 * @param principals * @return */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //获取前端输入的用户信息,封装为User对象 User userweb = (User) principals.getPrimaryPrincipal(); //获取前端输入的用户名 String username = userweb.getUsername(); //根据前端输入的用户名查询数据库中对应的记录 User user = userService.findByUsername(username); //如果数据库中有该用户名对应的记录,就进行授权操作 if (user != null){ SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); //因为addRoles和addStringPermissions方法需要的参数类型是Collection //所以先创建两个collection集合 Collection<String> rolesCollection = new HashSet<String>(); Collection<String> perStringCollection = new HashSet<String>(); //获取user的Role的set集合 Set<Role> roles = user.getRoles(); //遍历集合 for (Role role : roles){ //将每一个role的name装进collection集合 rolesCollection.add(role.getName()); //获取每一个Role的permission的set集合 Set<Permission> permissionSet = role.getPermissions(); //遍历集合 for (Permission permission : permissionSet){ //将每一个permission的name装进collection集合 perStringCollection.add(permission.getName()); } //为用户授权 info.addStringPermissions(perStringCollection); } //为用户授予角色 info.addRoles(rolesCollection); return info; }else{ return null; } } /** * 认证登录 * @param token * @return * @throws AuthenticationException */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //token携带了用户信息 UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; //获取前端输入的用户名 String userName = usernamePasswordToken.getUsername(); //根据用户名查询数据库中对应的记录 User user = userService.findByUsername(userName); //当前realm对象的name String realmName = getName(); //盐值 ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername()); //封装用户信息,构建AuthenticationInfo对象并返回 AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user, user.getPassword(), credentialsSalt, realmName); return authcInfo; } }
注:这个类也有详细的注释说明。
这样就完成了springboot对shiro的整合,接下来就可以进行测试了!
五、测试
tom登录
tom访问admin
tom访问test
cat登录
cat访问admin
cat访问test
测试结果与预期相符,测试通过,springboot整合shiro成功!
特别说明:
由于设置了MD5加密,所以数据库中存储的用户密码应该是加密后的密文,否则在登录页面输入明文会验证不通过。假如1234的密文为asdfghjkl,数据库中存储的应该是asdfghjkl,在登录时输入1234就能验证通过。
附上明文转密文的代码:
public static void main(String[] args) { String hashAlgorithName = "MD5"; String password = "登录时输入的密码"; int hashIterations = 1024;//加密次数 ByteSource credentialsSalt = ByteSource.Util.bytes("登录时输入的用户名"); Object obj = new SimpleHash(hashAlgorithName, password, credentialsSalt, hashIterations); System.out.println(obj); }
若不使用MD5加密
1、添加一个类
public class CredenttiaMatcher extends SimpleCredentialsMatcher{ @Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; String password = new String(usernamePasswordToken.getPassword()); String dbPassword = (String) info.getCredentials(); return this.equals(password,dbPassword); } }
2、将ShiroConfiguration.java中名为"hashedCredentialsMatcher"的bean替换成:
*@Bean("credenttiaMatcher") public CredenttiaMatcher credenttiaMatcher() { return new CredenttiaMatcher(); }
将名为"authRealm"的bean替换成:
@Bean("authRealm") @DependsOn("lifecycleBeanPostProcessor")//可选 public AuthRealm authRealm(@Qualifier("credenttiaMatcher") CredenttiaMatcher matcher) { AuthRealm authRealm = new AuthRealm(); authRealm.setCredentialsMatcher(matcher); return authRealm; }
3、AuthRealm.java中的doGetAuthenticationInfo方法里面的内容替换成:
//=========================未加密版========================== //token携带了用户登录的信息 UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token; //获取前端输入的用户名 String username = usernamePasswordToken.getUsername(); //根据前端输入的用户名查询数据库中的记录 User user = userService.findByUsername(username); //校验密码,验证登录 return new SimpleAuthenticationInfo(user,user.getPassword(),this.getClass().getName());
完成以上3步就去掉了MD5加密。
以上内容属于个人学习笔记整理,如有错误,欢迎批评指正!