-
授权需要继承 AuthorizingRealm 类, 并实现其 doGetAuthorizationInfo 方法
-
AuthorizingRealm 类继承自 AuthenticatingRealm, 但没有实现 AuthenticatingRealm 中的
doGetAuthenticationInfo, 所以认证和授权只需要继承 AuthorizingRealm 就可以了. 同时实现他的两个抽象方法.
-
为什么使用 MD5 盐值加密:
-
如何做到:
1). 在 doGetAuthenticationInfo 方法返回值创建 SimpleAuthenticationInfo 对象的时候, 需要使用
SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName) 构造器
2). 使用 ByteSource.Util.bytes() 来计算盐值.
3). 盐值需要唯一: 一般使用随机字符串或 user id
4). 使用 new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations); 来计算盐值加密后的密码的值. -
如何把一个字符串加密为 MD5
-
替换当前 Realm 的 credentialsMatcher 属性. 直接使用 HashedCredentialsMatcher 对象, 并设置加密算法即可.
密码的比对:
通过 AuthenticatingRealm 的 credentialsMatcher 属性来进行的密码的比对!
- 获取当前的 Subject. 调用 SecurityUtils.getSubject();
- 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject 的 isAuthenticated()
- 若没有被认证, 则把用户名和密码封装为 UsernamePasswordToken 对象
1). 创建一个表单页面
2). 把请求提交到 SpringMVC 的 Handler
3). 获取用户名和密码. - 执行登录: 调用 Subject 的 login(AuthenticationToken) 方法.
- 自定义 Realm 的方法, 从数据库中获取对应的记录, 返回给 Shiro.
1). 实际上需要继承 org.apache.shiro.realm.AuthenticatingRealm 类
2). 实现 doGetAuthenticationInfo(AuthenticationToken) 方法. - 由 shiro 完成对密码的比对.
realm
public class ShiroRealm extends AuthenticatingRealm {
@Autowired
private UserService userService;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
UsernamePasswordToken upToken= (UsernamePasswordToken) authenticationToken;
User user=userService.findUserByName(upToken.getUsername());
if(user==null){
System.out.println("用户不存在");
throw new UnknownAccountException("用户不存在");
}else if("master".equals(user.getName())){
System.out.println("用户被锁定");
throw new LockedAccountException("用户被锁定");
}
Object principal=user;//认证的实体信息
Object credentials=user.getPassword();//从数据库中获取的密码
String realmName=super.getName();//调用父类的getName()方法;
//盐值加密
ByteSource credentialsSalt = ByteSource.Util.bytes(upToken.getUsername());
return new SimpleAuthenticationInfo( principal, credentials, credentialsSalt, realmName);
}
}
## controller
````/**
* 登入
* @param name
* @param password
* @return
*/
@RequestMapping(value = "/doLogin",method = RequestMethod.POST)
public String login(@RequestParam("name") String name,@RequestParam("password") String password){
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()) {
UsernamePasswordToken token = new UsernamePasswordToken(name, password);
token.setRememberMe(true);
try {
currentUser.login(token);
}
//所有认证时候异常的父类
catch (AuthenticationException ae) {
System.out.println("登入失败");
return "redirect:/login.jsp";
}
}
return "success";
}
````