1、 maven jar 包引入
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-all</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.11</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.3.RELEASE</version> </dependency>
2、WebInitializer 加入 filter 对应的是 web.xml里
// 权限filter javax.servlet.FilterRegistration.Dynamic shiroFilter = servletContext.addFilter("shiroFilter", org.springframework.web.filter.DelegatingFilterProxy.class); shiroFilter.addMappingForUrlPatterns(null, false, "/*"); shiroFilter.setInitParameter("targetFilterLifecycle", "true");
3、编写 shiro filter
@Bean(name = "shiroFilter") public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必须设置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); SecurityUtils.setSecurityManager(securityManager); // 拦截器. Map<String, String> map = new LinkedHashMap<String, String>(); map.put("/c/logout/", "logout"); map.put("/c/login/", "anon"); map.put("/c/main/", "anon"); map.put("/c/shirologin/", "anon"); map.put("/c/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/c/main/"); // 未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; }
4、自定义AuthorizingRealm
@Autowired private UserService userService; //shiro的权限配置方法 @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { logger.info("权限配置-->doGetAuthorizationInfo"); SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); logger.info("----------------------------->"+principals.getPrimaryPrincipal()); User user=(User) principals.getPrimaryPrincipal(); for(Role role:user.getRoleList()){ authorizationInfo.addRole(role.getName()); for(Function function:role.getFunctionList()){ authorizationInfo.addStringPermission(function.getPermission()); } } logger.info("用户"+user.getUsername()+"具有的角色:"+authorizationInfo.getRoles()); logger.info("用户"+user.getUsername()+"具有的权限:"+authorizationInfo.getStringPermissions()); return authorizationInfo; } //shiro的身份验证方法 @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { logger.info("正在验证身份..."); SimpleAuthenticationInfo info=null; //将token转换成UsernamePasswordToken UsernamePasswordToken upToken = (UsernamePasswordToken) token; //从转换后的token中获取用户名 String username= upToken.getUsername(); logger.info("----->"+username); //查询数据库,得到用户 Map<String,Object> user = new HashMap(); List<Map<String, Object>> userlist = userService.getSysuserByUsername(username); if(userlist.size() == 0){ return null; }else{ user = userlist.get(0); } //得到加密密码的盐值 ByteSource salt = ByteSource.Util.bytes(user.get("password").toString()); info = new SimpleAuthenticationInfo( user, //用户名 user.get("password").toString(), //密码 salt, //加密的盐值 getName() //realm name ); return info; } /** * 设定Password校验. */ @PostConstruct public void initCredentialsMatcher() { //该句作用是重写shiro的密码验证,让shiro用我自己的验证 setCredentialsMatcher(new CustomCredentialsMatcher()); }
5、自定义密码校验 复写SimpleCredentialsMatcher
@Override public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { UsernamePasswordToken token = (UsernamePasswordToken) authcToken; JSONObject jsonObject = new JSONObject(info); System.out.println(jsonObject); Object accountCredentials = getCredentials(info); //将密码加密与系统加密后的密码校验,内容一致就返回true,不一致就返回false try { return PasswordUtils.validatePassword(String.valueOf(token.getPassword()), jsonObject.getString("credentials")); } catch (JSONException e) { e.printStackTrace(); return false; } }
附录:QQ365810157 有相关兴趣爱好者可以 相互学习借鉴