我和shiro有个故事02
springboot+shiro ----------- 明文密码方式
表还是那三张表
user表
(此篇忽略salt盐和加密的密码。这篇使用的明文密码)
role 角色表
权限表
maven 除了基本的spring包还需要shiro包
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
----------------------------------------------------------------------------------------------------------------
我们需要一个 MyShiroRealm 类来做验证和授权的事情
public class MyShiroRealm extends AuthorizingRealm {
@Autowired
private UserDao userDao;
//权限信息,包括角色以及权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("权限验证----");
String account = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
try {
User user =new User();
user.setAccount(account);
authorizationInfo.setRoles(userDao.selectRoleByAccount(user));
// authorizationInfo.setStringPermissions(userDao.getPermissions(user));
} catch (Exception e) {
e.printStackTrace();
}finally{
}
return authorizationInfo;
}
/*主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("登录验证-------");
String account= (String) token.getPrincipal();
try {
User user_param =new User();
user_param.setAccount(account);
User user = userDao.selectUserByAccount(user_param);
if(user!=null){
ByteSource salt = ByteSource.Util.bytes(user.getSalt());
AuthenticationInfo authcInfo =new SimpleAuthenticationInfo(user.getAccount(),user.getPassword(),"xx");//明文密码验证
// AuthenticationInfo authcInfo =new SimpleAuthenticationInfo(user.getAccount(),user.getPassword(),salt,"xx"); // 加盐加密码的验证
return authcInfo;
}else{
return null;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
一些需要的查询如下
<select id="selectUserByAccount" resultType="User">
select * from tb_user where account=#{account} limit 1;
</select>
<select id="selectRoleByAccount" resultType="string">
select r.rolename from tb_user u,tb_role r where u.roleid = r.roleid and u.account = #{account}
</select>
需要一个shiroconfig来初始化配置
@Configuration
public class ShiroConfig {
@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");
filterChainDefinitionMap.put("/layui/**", "anon");
filterChainDefinitionMap.put("/UserController/**", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//<!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
//<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login.html");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index.html");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403.html");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 凭证匹配器
* (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
* )
* @return
*/
@Bean
public SimpleCredentialsMatcher hashedCredentialsMatcher(){
// SimpleCredentialsMatcher 对象使用明文验证密码
// HashedCredentialsMatcher 对象使用加密的方式验证密码
// HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
// hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
// hashedCredentialsMatcher.setHashIterations(1);//散列的次数,比如散列两次,相当于 md5(md5(""));
// return hashedCredentialsMatcher;
SimpleCredentialsMatcher simpleCredentialsMatcher =new SimpleCredentialsMatcher();
return simpleCredentialsMatcher;
}
@Bean
public MyShiroRealm myShiroRealm(){
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
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;
// }
}
登录controller验证
String account = user.getAccount();
String password = user.getPassword();
Subject subject = SecurityUtils.getSubject();
//session 失效时间
subject.getSession().setTimeout(60*30*1000L);
UsernamePasswordToken token = new UsernamePasswordToken(account, password);
subject.login(token);
Session session = subject.getSession();