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;
}
}