1.pom引入依赖
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version> </dependency>
2.Ream实体类
package com.test.test.controller;//package com.shiro.shiro.config; import com.test.test.entity.SysUser; import com.test.test.mapper.SysUserDao; import org.apache.shiro.authc.*; import org.apache.shiro.authc.credential.CredentialsMatcher; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import java.util.HashSet; import java.util.List; import java.util.Set; //@Service public class UserRealm extends AuthorizingRealm { @Autowired private SysUserDao sysUserDao; //ConcurrentHashMap()在jdk1.5之后推出,在1.8和1.8之后 //添加了红黑树 /*private Map<String, SimpleAuthorizationInfo> authMap= new ConcurrentHashMap<String, SimpleAuthorizationInfo>();*/ /*** * 完成授权信息的获取以及封装. * 此方法何时调用?(执行授权检测时调用) * */ @Override protected AuthorizationInfo doGetAuthorizationInfo( PrincipalCollection principals) { // System.out.println("realm.doGetAuthorizationInfo"); // //1.获取登陆用户身份信息,(基于登录认证时传递的主身份) // String username= // (String)principals.getPrimaryPrincipal(); // //查询缓存中是否有这个 // /*if(authMap.containsKey(username)) // return authMap.get(username);*/ // //2.查找用户的权限信息 // List<String> list=//sys:user:update,sys:user:view,...., // sysUserDao.findUserPermissions(username); // System.out.println("list="+list); // //去重去空 // Set<String> permissions=new HashSet<String>(); // for(String permission:list){ // if(!StringUtils.isEmpty(permission)){ // permissions.add(permission); // } // } // System.out.println("====查询认证信息"); // //3.对权限信息进行封装 // SimpleAuthorizationInfo info= // new SimpleAuthorizationInfo(); // info.setStringPermissions(permissions); // /*authMap.put(username, info);*/ // return info; return null; } /** * 完成认证信息的获取以及封装 * 此方法何时调用?(执行登陆认证时调用) * @param * //用于接收用户身份以及凭证信息的对象(用户输入的) * * @return AuthenticationInfo * 封装了认证信息的对象(从数据库查询到的) * * client-->controller-->service-->realm */ @Override protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken token) throws AuthenticationException { System.out.println("进行身份认证"); //1.获取用户身份信息 UsernamePasswordToken uToken= (UsernamePasswordToken)token; String username=uToken.getUsername(); //String username=token.getPrintcipal(); //2.基于用户身份查询数据库信息 SysUser sysUser = sysUserDao.findUserByUserName(username); if(sysUser==null) throw new UnknownAccountException("密码或账号错误"); if(sysUser.getValid()==0){ throw new LockedAccountException("用户被锁定"); } //3.对查询结果进行封装. //3.1获取用户salt值,并将其转换为一个字节源对象 ByteSource byteSource= ByteSource.Util.bytes(sysUser.getSalt()); //3.2对用户信息进行封装返回. AuthenticationInfo info= new SimpleAuthenticationInfo( sysUser.getUsername(), //主身份 sysUser.getPassword(), //已加密的密码 byteSource,//salt对应的字节源对象 getName());//realm 的名字 return info; } /** * 设置凭证(密码)匹配器 */ @Override public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) { HashedCredentialsMatcher hMatcher = new HashedCredentialsMatcher(); //设置加密算法 hMatcher.setHashAlgorithmName("MD5"); //设置加密次数 //hMatcher.setHashIterations(5); super.setCredentialsMatcher(hMatcher); } }
3.配置类
package com.test.test.controller;//package com.shiro.shiro; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; import org.apache.shiro.mgt.SecurityManager; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @Configuration public class SharioConfig001 { @Bean public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //拦截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>(); // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录 filterChainDefinitionMap.put("/css/**", "anon"); filterChainDefinitionMap.put("/fonts/**", "anon"); filterChainDefinitionMap.put("/img/**", "anon"); filterChainDefinitionMap.put("/js/**", "anon"); filterChainDefinitionMap.put("/html/**", "anon"); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); //<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> filterChainDefinitionMap.put("/**", "authc"); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/index"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 凭证匹配器 * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 * ) * @return */ @Bean public UserRealm userRealm(){ UserRealm myShiroRealm = new UserRealm(); // myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } @Bean public SecurityManager securityManager(){ DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm()); return securityManager; } /** * 开启shiro aop注解支持. * 使用代理方式;所以需要开启代码支持; * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean(name="simpleMappingExceptionResolver") public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() { SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理 mappings.setProperty("UnauthorizedException","/user/403"); r.setExceptionMappings(mappings); // None by default r.setDefaultErrorView("error"); // No default r.setExceptionAttribute("exception"); // Default is "exception" //r.setWarnLogCategory("example.MvcLogger"); // No default return r; } }