现在开始实现框架的登录授权功能。
1.从客户端获取用户名,密码,是否记住等信息,生成token,通过subject.login(token)进行登录验证,如下:
public void login()
{
String username = getPara("username");
String password = getPara("password");
String rememberMe = getPara("rememberMe");
UsernamePasswordToken token = new UsernamePasswordToken(username, password, StrKit.notBlank(rememberMe) ? true : false);
Subject subject = SecurityUtils.getSubject();
try
{
//登录,即身份验证
subject.login(token);
redirect("/");
return;
}
catch (AuthenticationException e)
{
//身份验证失败
}
}
2.这里再简单叙述下验证及授权流程,作为上几篇认证和授权的总结。
(1)启动jfinal,会首先加载web.xml,并实例化里面的类,这里会创建EnvironmentLoaderListener的实例。EnvironmentLoaderListener在容器启动时创建 WebEnvironment 对象,并由该对象来读取 Shiro 配置文件,创建WebSecurityManager 与 FilterChainResolver 对象,同时创建一些有用的内置过滤器实例,并且自动的在[main]部分使用。如.ini文件配置,要使用authc,先定义其使用的类,这个类必须实现AuthenticatingFilter。
(2)调用方法subject.login(token)进行登录,最终委托接口SecurityManage的实现类的login方法。
(3)调用login方法的过程是:Authenticator会把相应的token传入Realm,从Realm获取身份验证信息,权限信息,然后进行身份验证和权限验证。
(4)ShiroRealm具体实现如下:
public class ShiroRealm extends AuthorizingRealm
{
// 用户服务类
private final UserService userService = UserService.me();
// 角色服务类
private final RoleService roleService = RoleService.me();
// 权限服务类
private final PermissionService permissionService = PermissionService.me();
/**
* 获取登录用户拥有的角色和权限
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
{
String username = (String)principals.getPrimaryPrincipal();//当前登录用户名
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
User user = userService.findByUsername(username); //根据用户名查找用户信息
List<Role> roles = roleService.findRolesByUserId(user.getId());//根据用户名查找角色
if(roles != null && roles.size() > 0)
{
for(Role role : roles)
{
authorizationInfo.addRole(role.getName());//将当前用户名下的角色存入authorizationInfo
}
}
List<Permission> permissions = permissionService.findUserPermsByUserId(user.getId());
if(permissions != null && permissions.size() > 0)
{
for(Permission permission : permissions)
{
authorizationInfo.addStringPermission(permission.getPermissionName());//将当前用户名下的权限存入authorizationInfo
}
}
return authorizationInfo;
}
/**
* 验证用户是否合法
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
{
String username = (String)token.getPrincipal(); //当前登录用户名
User user = userService.findByUsername(username); //根据用户名查找用户信息
if(StrKit.isBlank(username))
{
throw new AuthenticationException("用户名不可以为空");
}
if (user == null)
{
throw new AuthenticationException("用户名或者密码错误");
}
return new SimpleAuthenticationInfo(user, user.getPassword(), getName()); //存入查询用户信息
}
}