SpringBoot配置shiro
1先导入jar包
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<!-- html页面中加shiro标签所需依赖 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
2.写Controller,controller在调用shiro授权和认证
@RequestMapping("/checkLogin")
public String checkLogin(Users users) {
System.out.println("进入Controller");
//添加用户认证信息
Subject subject= SecurityUtils.getSubject();
UsernamePasswordToken usernamePasswordToken=new UsernamePasswordToken(users.getuName(),users.getuPwd());
try{
//进行验证,这里可以捕获异常,然后返回对应的信息
subject.login(usernamePasswordToken);
}catch(AuthorizationException e){
e.printStackTrace();
System.out.println("身份认证失败");
return "login";
}catch(AuthenticationException e){
e.printStackTrace();
return "login";
}
System.out.println("认证成功");
return "index";
}
3.在config里面添加ShiroConfig以及ShiroProperties配置文件
package hospital.hospitalsystem.config;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.wu.hospitalsystem.realm.CustomRealm;
import org.apache.shiro.mgt.SecurityManager;
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.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
//从容器中拿去url配置规则
@Autowired
private ShiroProperties shiroProperties;
@Bean
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
defaultAAP.setProxyTargetClass(true);
return defaultAAP;
}
//页面添加shiro标签以后,通过这个方法找到授权的方法
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
//将自己的验证方式加入容器
@Bean
public CustomRealm myShiroRealm() {
CustomRealm customRealm = new CustomRealm();
return customRealm;
}
//权限管理,配置主要是Realm的管理认证
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
//Filter工厂,设置对应的过滤条件和跳转条件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//以下注释部分,还可以将配置定义到yaml中
Map<String, String> map = new HashMap<>();
//表示可以匿名访问
map.put("/login","anon"); //详细规则请见本目录下URL匹配规则.md文件
//表示可以匿名访问
map.put("/checkLogin","anon"); //详细规则请见本目录下URL匹配规则.md文件
//登出
map.put("/logout", "logout");
//对所有用户认证
map.put("/**", "authc");//authc表示需要认证才可以访问,anon表示可以匿名访问
//登录
shiroFilterFactoryBean.setLoginUrl("/login");
//首页
shiroFilterFactoryBean.setSuccessUrl("/index");
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
4.配置ShiroProperties
package hospital.hospitalsystem.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author: create by wangmh
* @projectName: Shiro_example 从yaml文件中获取url匹配规则
* @packageName: com.shiro.configuration
* @description:
* @date: 2019/10/9
**/
@Data
@Component
@ConfigurationProperties(prefix = "shiro")
public class ShiroProperties {
private Map<String,String> filterChainDefinitionMap;
public Map<String, String> getFilterChainDefinitionMap() {
return filterChainDefinitionMap;
}
public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) {
this.filterChainDefinitionMap = filterChainDefinitionMap;
}
}
5.创建realm包 在创建CustomRealm继承AuthorizingRealm
package com.wu.hospitalsystem.realm;
import com.wu.hospitalsystem.Service.UserRoleService;
import com.wu.hospitalsystem.Service.UserService;
import com.wu.hospitalsystem.pojo.Users;
import com.wu.hospitalsystem.pojo.UsersRole;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
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.springframework.beans.factory.annotation.Autowired;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class CustomRealm extends AuthorizingRealm {
@Autowired
UserService userService;
@Autowired
UserRoleService userRoleService;
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("开始授权");
//获取登录用户名
String name=(String) principalCollection.getPrimaryPrincipal();
Set<String> roles=new HashSet<>();
//根据用户名去数据库查询用户信息
UsersRole usersRole=userRoleService.getUserRolebyName(name);
//添加角色和权限
System.out.println(usersRole.getRole().getrName());
roles.add(usersRole.getRole().getrName());
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles);
return info;
}
//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("开始认证");
//加这一步的目的是在post请求的时候会先进认证,然后在到请求
if (authenticationToken.getPrincipal() == null) {
return null;
}
//获取用户信息
String name = authenticationToken.getPrincipal().toString();
List<Users> list = userService.getUserbyName(name);
if (list.size() == 0) {
//这里返回会报出异常
System.out.println("认证失败,暂无次用户");
return null;
} else {
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, list.get(0).getuPwd(), getName());
return simpleAuthenticationInfo;
}
}
}
6.认证会通过用户名调用数据库,和以前的一样,通过用户名查询数据库
直接写serviceImpl调用数据库方法
//根据用户名查询
@Override
public List<Users> getUserbyName(String name) {
Example example=new Example(Users.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("uName",name);
List<Users> list= userMapper.selectByExample(example);
return list;
}
7.授权的话,需要连表查询,使用的是通用mapper,所有需要自己写sql
service接口类
public interface UserRoleService {
UsersRole getUserRolebyName(String name);
}
service实现类
@Override
public UsersRole getUserRolebyName(String name) {
Users user=new Users();
user.setuName(name);
return userRoleMapper.getUserRoleByName(user);
}
dao层
public interface UserRoleMapper {
UsersRole getUserRoleByName(Users user);
}
8.下面开始写自定义sql
mybatis-config,xml中添加内容,扫描xml映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<mappers>
<mapper resource="mybatis/mapper/UsersRoleMapper.xml"/>
</mappers>
</configuration>
UsersRoleMapper.xml中写自定义sql
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wu.hospitalsystem.mapper.UserRoleMapper">
<resultMap id="usersRoleMapper" type="com.wu.hospitalsystem.pojo.UsersRole">
<id column="ur_id" property="urId"/>
<result column="u_id" property="uId"/>
<result column="r_id" property="rId"/>
<association property="users" javaType="com.wu.hospitalsystem.pojo.Users">
<id column="u_id" property="uId"/>
<result column="u_name" property="uName"/>
<result column="u_pwd" property="uPwd"/>
</association>
<association property="role" javaType="com.wu.hospitalsystem.pojo.Role">
<id column="r_id" property="rId"/>
<result column="r_name" property="rName"/>
</association>
</resultMap>
<select id="getUserRoleByName" resultMap="usersRoleMapper" resultType="com.wu.hospitalsystem.pojo.Users">
select u.u_name ,u.u_pwd,r.r_name from users_role ur
LEFT JOIN users u ON ur.u_id=u.u_id
LEFT JOIN role r on ur.r_id=r.r_id
where u.u_name=#{uName}
</select>
</mapper>
9.下面在写页面调用shiro标签
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<title>xx市第二人民医院信息管理系统</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="assets/css/dpl-min.css" rel="stylesheet" type="text/css" />
<link href="assets/css/bui-min.css" rel="stylesheet" type="text/css" />
<link href="assets/css/main-min.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="assets/js/jquery-1.6.js"></script>
<script type="text/javascript" src="assets/js/bui.js"></script>
<script type="text/javascript" src="assets/js/common/main-min.js"></script>
<script type="text/javascript" src="assets/js/config-min.js"></script>
<script>
var isadmin=false;
var ismanager=false;
</script>
</head>
<body>
<shiro:hasRole name="admin">
<script>
isadmin=true;
ismanager=false;
</script>
</shiro:hasRole>
<shiro:hasRole name="manager">
<script>
isadmin=false;
ismanager=true;
</script>
</shiro:hasRole>
<div class="header">
<div class="dl-title">
<!--<img src="/chinapost/Public/assets/img/top.png">-->
</div>
<div class="dl-log">欢迎您,<span class="dl-log-user" th:text="${session.uName}"></span>
<a href="logout" title="退出系统" class="dl-log-quit">[退出]</a>
</div>
</div>
<div class="content">
<div class="dl-main-nav">
<div class="dl-inform">
<div class="dl-inform-title">
<s class="dl-inform-icon dl-up">
</s>
</div>
</div>
<ul id="J_Nav" class="nav-list ks-clear">
<li class="nav-item dl-selected">
<div class="nav-item-inner nav-home">医院管理系统</div>
</li>
</ul>
</div>
<ul id="J_NavContent" class="dl-tab-conten">
</ul>
</div>
<script>
BUI.use('common/main',function(){
var config = [
{id:'1',menu:[
{text:'快速通道',items:[
{id:'2',text:'挂号信息管理',href:'registration/index.html'},
{id:'3',text:'门诊医生管理',href:'doctor/index.html'},
{id:'4',text:'药品管理',href:'medicine/index.html'},
{id:'5',text:'住院办理',href:'hospital/index.html'},
{id:'6',text:'收费项目登记',href:'hospital/charge.html'},
{id:'7',text:'在院发药',href:'hospital/dispensing.html'},
{id:'8',text:'住院结算',href:'hospital/account.html'},
{id:'11',text:'用户管理',href:'User/index.html'},
{id:'12',text:'角色管理',href:'Role/index.html'},
{id:'13',text:'资源管理',href:'Resource/index.html'},
{id:'14',text:'密码设置 ',href:'Resource/index.html'}
]}
]}
];
if (ismanager){
config[0].menu[0].items.splice(7,3);
}
new PageUtil.MainPage({
modulesConfig : config
});
});
</script>
</body>
</html>