springmvc集成shiro例子
仅供参考
仅供参考
登录部分
代码:
@RequestMapping(value = "/login", method = RequestMethod.GET) @ResponseBody public Map<String, Object> login(HttpServletRequest request) { Map<String, Object> resultMap = new LinkedHashMap<String, Object>(); 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),这个方法会调用org.apache.shiro.realm.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(); Set<String> roles = new HashSet<String>(); roles.add("admin"); //roles.add("role1"); Set<String> permissions = new HashSet<String>(); permissions.add("add"); permissions.add("delete"); sainfo.setRoles(roles); sainfo.setStringPermissions(permissions); return sainfo; }
注意,一般是根据用户名从数据库中查找该用户的角色和权限,进行授权;当然其它途径也是可以的,如webservice接口,配置文件等获取用户权限。
权限拦截配置
如下:
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"></property> <property name="loginUrl" value="/security/view/login"></property> <property name="successUrl" value="/successUrl"></property> <!-- 用户访问未对其授权的资源时,所显示的连接 --> <property name="unauthorizedUrl" value="/unauthorizedUrl"></property> <property name="filters"> <map> <entry key="anyRoles"> <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" /> </entry> </map> </property> <property name="filterChainDefinitions"> <value> /security/**=anon /test/**=roles[role1] /users/**=anyRoles[admin,role1] /**=authc </value> </property> </bean>
根据用户的角色或权限来配置对应匹配的访问路径;
访问路径匹配任意角色
默认情况下,配置权限控制的时候,如
/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属性,如下,
<property name="filters"> <map> <entry key="anyRoles"> <bean class="cn.edu.hdu.ssd.core.shiro.AnyRolesAuthorizationFilter" /> </entry> </map> </property>
最后,权限拦截配置可以这样配:
/test/**=anyRoles[admin,role1]
示例源码参考
https://github.com/peterchenhdu/spring-shiro-demo