仅供参考
仅供参考
登录部分
代码:
@RequestMapping(value = "/login", method = RequestMethod.GET) @ResponseBody public Maplogin(HttpServletRequest request) { Map resultMap = new LinkedHashMap (); try { ShiroToken token = new ShiroToken("admin", "21232f297a57a5a743894a0e4a801fc3"); token.setRememberMe(false); SecurityUtils.getSubject().login(token); ShiroToken token2 = (ShiroToken) SecurityUtils.getSubject().getPrincipal(); logger.info(token2.getUsername() + "," + token2.getPswd()); resultMap.put("status", 200); resultMap.put("message", "登录成功"); /** * 获取登录之前的地址 */ SavedRequest savedRequest = WebUtils.getSavedRequest(request); String url = null; if (null != savedRequest) { url = savedRequest.getRequestUrl(); } // 跳转地址 resultMap.put("back_url", url); } catch (DisabledAccountException e) { resultMap.put("status", 500); resultMap.put("message", "帐号已经禁用。"); } catch (Exception e) { resultMap.put("status", 500); resultMap.put("message", "帐号或密码错误"); } return resultMap; }
注意几点:
1、登录密码记得加密,一般存在数据库中的密码是加密过的。
2、真正开始执行登录操作的是SecurityUtils.getSubject().login(token),这个方法会调用....AuthorizingRealm的doGetAuthenticationInfo方法进行登录认证:
3、出错异常记得捕获
登录验证部分
代码如下:
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) { ShiroToken token = (ShiroToken) arg0; String username = token.getUsername(); // 根据username从数据库查找用户,得到密码 // 假设找到的用户如下 // User user = userService.findByUsername(username) User user = new User(); user.setName(username); user.setPassword("21232f297a57a5a743894a0e4a801fc3"); // 数据库中的密码md5加密的 if (null == user) { throw new AccountException("username is not exist"); } else if (!user.getPassword().equals(token.getPswd())) { throw new AccountException("password is not right"); } else { // 登陆成功 logger.info("{} login success.", username); } return new SimpleAuthenticationInfo(arg0, user.getPassword(), username); }
注意几点:
1、一般会根据username从数据库中查找该用户,得到密码
2、进行密码校验,判断一致性
3、根据获取到的用户信息,也可以进行其它判断,如用户是否激活,是否被禁用等
授权部分
代码如下:
@Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { ShiroToken token = (ShiroToken) SecurityUtils.getSubject().getPrincipal(); String username = token.getUsername(); logger.info(username + "授权..."); // 从数据库中查找该用户的角色和权限 SimpleAuthorizationInfo sainfo = new SimpleAuthorizationInfo(); Setroles = new HashSet (); roles.add("admin"); //roles.add("role1"); Set permissions = new HashSet (); permissions.add("add"); permissions.add("delete"); sainfo.setRoles(roles); sainfo.setStringPermissions(permissions); return sainfo; }
注意,一般是根据用户名从数据库中查找该用户的角色和权限,进行授权;当然其它途径也是可以的,如webservice接口,配置文件等获取用户权限。
权限拦截配置
如下:
/security/**=anon /test/**=roles[role1] /users/**=anyRoles[admin,role1] /**=authc
根据用户的角色或权限来配置对应匹配的访问路径;
访问路径匹配任意角色
默认情况下,配置权限控制的时候,如
/test/**=roles[role1,admin]
结果是需要用户同时拥有role1和admin权限才能访问/test/**路径,这往往不符合我们的需求,
大部分情况,我们希望的是用户拥有role1和admin任一角色即可。
那么可以这样修改,编写一个过滤器:
public class AnyRolesAuthorizationFilter extends AuthorizationFilter{ // private Logger logger = LoggerFactory.getLogger(ShiroCasAuthFilter.class); @Override protected boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws Exception { Subject subject = getSubject(req, resp); String[] rolesArray = (String[]) mappedValue; if (rolesArray == null || rolesArray.length == 0) { return true; } for (int i = 0; i < rolesArray.length; i++) { if (subject.hasRole(rolesArray[i])) { return true; } } return false; }}
配置shiroFilter bean的filters属性,如下,
最后,权限拦截配置可以这样配:
/test/**=anyRoles[admin,role1]