网上关于springboot2.0和shiro+myabtis整合的案例很少,大神的教程也是用jpa编写,jpa很方便,但是还有很多人用mybatis,加之刚学习完mybatis多数据源整合和druid连接池监控配置,所以算是阶段性记录。
4.0.0
com.example
mybatisdemo
0.0.1-SNAPSHOT
jar
mybatisdemo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
UTF-8
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
runtime
org.springframework.boot
spring-boot-devtools
true
com.alibaba
druid-spring-boot-starter
1.1.10
org.apache.commons
commons-lang3
org.springframework.boot
spring-boot-configuration-processor
true
org.apache.shiro
shiro-spring
1.4.0
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-maven-plugin
server:
port: 8080
spring:
datasource:
druid:
test1:
#配置监控统计拦截的filters,去掉后监控界面SQL无法进行统计,'wall'用于防火墙
filters: stat,wall
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: root
#初始化大小
initial-size: 1
#最小连接数
min-idle: 1
#最大连接数
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久才进行一次检测,检测需要关闭的空闲连接,单位毫秒
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
#测试语句是否执行正确
validation-query: SELECT 'x'
#指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除.
test-while-idle: true
#借出连接时不要测试,否则很影响性能
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
#与Oracle数据库PSCache有关,再druid下可以设置的比较高
max-pool-prepared-statement-per-connection-size: 20
#数据源2
test2:
filters: stat,wall
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/mytest2?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
username: root
password: root
initial-size: 1
min-idle: 1
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 30000
validation-query: SELECT 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
thymeleaf:
cache: false
mode: LEGACYHTML5
package com.example.mybatisdemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@MapperScan(basePackages = "com.example.mybatisdemo.dao1",sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.test1")
@Primary
public DruidDataSource test1DataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory test1sqlSessionFactory(@Qualifier("test1DataSource") DruidDataSource druidDataSource) throws Exception{
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(druidDataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource")DruidDataSource druidDataSource){
return new DataSourceTransactionManager(druidDataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory")SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.example.mybatisdemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@MapperScan(basePackages = "com.example.mybatisdemo.dao2",sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.druid.test2")
// @Primary
public DruidDataSource test2DataSource(){
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
// @Primary
public SqlSessionFactory test2sqlSessionFactory(@Qualifier("test2DataSource") DruidDataSource druidDataSource) throws Exception{
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(druidDataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
// @Primary
public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource")DruidDataSource druidDataSource){
return new DataSourceTransactionManager(druidDataSource);
}
@Bean(name = "test2SqlSessionTemplate")
// @Primary
public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory")SqlSessionFactory sqlSessionFactory){
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.example.mybatisdemo.config;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DruidConfig {
/**
* 注册servlet信息,配置监控图
*
*/
@Bean
@ConditionalOnMissingBean
public ServletRegistrationBean druidServlet(){
ServletRegistrationBean servletRegistrationBean =
new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
//白名单
servletRegistrationBean.addInitParameter("allow","192.168.6.195");
//IP黑名单(存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
servletRegistrationBean.addInitParameter("deny","192.168.6.73");
//用于登陆的账号密码
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","admin");
//是否能重置数据
servletRegistrationBean.addInitParameter("resetEnable","true");
return servletRegistrationBean;
}
/**
*
* 注册filter信息,用于拦截
*/
@Bean
@ConditionalOnMissingBean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
RBAC 是基于角色的访问控制(Role-Based Access Control )在 RBAC 中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
CREATE TABLE `sys_permission` (
`id` int(11) NOT NULL,
`available` bit(1) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`parent_id` bigint(20) DEFAULT NULL,
`parent_ids` varchar(255) DEFAULT NULL,
`permission` varchar(255) DEFAULT NULL,
`resource_type` enum('menu','button') DEFAULT NULL,
`url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
CREATE TABLE `sys_role` (
`id` int(11) NOT NULL,
`available` bit(1) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`role` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
CREATE TABLE `user_info` (
`uid` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`salt` varchar(255) DEFAULT NULL,
`state` tinyint(4) NOT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
CREATE TABLE `sys_role_permission` (
`permission_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
KEY `FK9q28ewrhntqeipl1t04kh1be7` (`role_id`),
KEY `FKomxrs8a388bknvhjokh440waq` (`permission_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
CREATE TABLE `sys_user_role` (
`role_id` int(11) NOT NULL,
`uid` int(11) NOT NULL,
KEY `FKgkmyslkrfeyn9ukmolvek8b8f` (`uid`),
KEY `FKhh52n8vd4ny9ff4x9fb8v65qx` (`role_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4
INSERT INTO `user_info` (`uid`,`username`,`name`,`password`,`salt`,`state`) VALUES ('1', 'admin', '管理员', 'd3c59d25033dbf980d29554025c23a75', '8d78869f470951332959580424d4bf4f', 0);
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (1,0,'用户管理',0,'0/','userInfo:view','menu','userInfo/userList');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (2,0,'用户添加',1,'0/1','userInfo:add','button','userInfo/userAdd');
INSERT INTO `sys_permission` (`id`,`available`,`name`,`parent_id`,`parent_ids`,`permission`,`resource_type`,`url`) VALUES (3,0,'用户删除',1,'0/1','userInfo:del','button','userInfo/userDel');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (1,0,'管理员','admin');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (2,0,'VIP会员','vip');
INSERT INTO `sys_role` (`id`,`available`,`description`,`role`) VALUES (3,1,'test','test');
INSERT INTO `sys_role_permission` VALUES ('1', '1');
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (1,1);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (2,1);
INSERT INTO `sys_role_permission` (`permission_id`,`role_id`) VALUES (3,2);
INSERT INTO `sys_user_role` (`role_id`,`uid`) VALUES (1,1);
package com.example.mybatisdemo.domain;
public class Permission {
private Integer id;
private Boolean available;
private String name;
private Long parent_id;
private String parent_ids;
private String permission;
private String resource_type;
private String url;}
package com.example.mybatisdemo.domain;
public class Role {
private Integer id;
private Boolean available;
private String description;
private String role;
}
package com.example.mybatisdemo.domain;
public class UserInfo {
private Integer uid;
private String name;
private String username;
private String password;
private String salt;
private byte state;
//密码加盐
public String getCredentialsSalt(){
return this.username+this.salt;
}
}
盐值由数据库中的salt和账号组合而成
因为多数据源配置,dao层有两个并分开使用,可以一个设计数据一个设计用户验证,这里只实现用户验证放dao1中
package com.example.mybatisdemo.dao1;
import com.example.mybatisdemo.domain.Permission;
import com.example.mybatisdemo.domain.Role;
import com.example.mybatisdemo.domain.UserInfo;
import java.util.List;
public interface UserInfoDao {
UserInfo selectByUsername(String username);
List selectRoleidByUid(Integer uid);
Role selectRoleById(Integer id);
List selectPermissionidByRoleid(Integer roleid);
Permission selectPermissionById(Integer permissionid);
}
uid,name,password,salt,state,username
user_info
username
role_id
sys_user_role
id,available,description,role
sys_role
permission_id
sys_role_permission
id,available,name,parent_id,parent_ids,permission,resource_type,url
sys_permission
package com.example.mybatisdemo.service;
import com.example.mybatisdemo.domain.Permission;
import com.example.mybatisdemo.domain.Role;
import com.example.mybatisdemo.domain.UserInfo;
import java.util.List;
public interface UserInfoService {
UserInfo findByUsername(String username);
Role findRoleById(Integer id);
List findRoleidByUid(Integer uid);
List findPermissionidByRoleid(Integer roleid);
Permission findPermissionById(Integer permissionid);
}
package com.example.mybatisdemo.service.impl;
import com.example.mybatisdemo.dao1.UserInfoDao;
import com.example.mybatisdemo.domain.Permission;
import com.example.mybatisdemo.domain.Role;
import com.example.mybatisdemo.domain.UserInfo;
import com.example.mybatisdemo.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service(value = "userInfoService")
public class UserInfoServiceImpl implements UserInfoService {
@Autowired
private UserInfoDao userInfoDao;
@Override
public UserInfo findByUsername(String username) {
return userInfoDao.selectByUsername(username);
}
@Override
public Role findRoleById(Integer id) {
return userInfoDao.selectRoleById(id);
}
@Override
public List findRoleidByUid(Integer uid) {
return userInfoDao.selectRoleidByUid(uid);
}
@Override
public List findPermissionidByRoleid(Integer roleid) {
return userInfoDao.selectPermissionidByRoleid(roleid);
}
@Override
public Permission findPermissionById(Integer permissionid) {
return userInfoDao.selectPermissionById(permissionid);
}
}
package com.example.mybatisdemo.config;
import com.example.mybatisdemo.domain.UserInfo;
import com.example.mybatisdemo.service.UserInfoService;
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.apache.shiro.util.ByteSource;
import javax.annotation.Resource;
public class MyshiroRealm extends AuthorizingRealm {
@Resource
private UserInfoService userInfoService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
UserInfo userInfo = (UserInfo) principalCollection.getPrimaryPrincipal();
for (Integer integer : userInfoService.findRoleidByUid(userInfo.getUid())){
authorizationInfo.addRole(userInfoService.findRoleById(integer).getRole());
for (Integer id : userInfoService.findPermissionidByRoleid(integer)){
authorizationInfo.addStringPermission(userInfoService.findPermissionById(id).getPermission());
}
}
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
System.out.println("我在执行登陆验证-----");
String username = (String)authenticationToken.getPrincipal();
System.out.println("token.getCredentials()-----"+authenticationToken.getCredentials());
UserInfo userInfo = userInfoService.findByUsername(username);
System.out.println("userInfo-----"+userInfo);
if (userInfo == null){
return null;
}
System.out.println(userInfo.getCredentialsSalt());
System.out.println(userInfo.getPassword());
SimpleAuthenticationInfo authorizationInfo = new SimpleAuthenticationInfo(
userInfo,
userInfo.getPassword(),
ByteSource.Util.bytes(userInfo.getCredentialsSalt()),
getName()
);
return authorizationInfo;
}
}
package com.example.mybatisdemo.config;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shriofilter(SecurityManager securityManager){
System.out.println("ShiroConfiguration.shirFilter()");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器
Map filterChainDefinitionMap = new LinkedHashMap<>();
//配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/registered","anon");
filterChainDefinitionMap.put("/nofilter/**","anon");
//配置退出过滤器 其中具体代码已经被Shiro帮忙实现了
filterChainDefinitionMap.put("/logout","logout");
//:这是一个坑呢,一不小心代码就不好使了;
//
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 HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//md5散列算法
hashedCredentialsMatcher.setHashIterations(2);//散列次数
return hashedCredentialsMatcher;
}
@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
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver
createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");//数据库异常处理
mappings.setProperty("UnauthorizedException","403");
r.setExceptionMappings(mappings); // None by default
r.setDefaultErrorView("error"); // No default
r.setExceptionAttribute("ex"); // Default is "exception"
//r.setWarnLogCategory("example.MvcLogger"); // No default
return r;
}
}
package com.example.mybatisdemo.web;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
public class HomeController {
@RequestMapping({"/","/index"})
public String index(){
return "/index";
}
@RequestMapping("/login")
public String login(HttpServletRequest request, Map map) throws Exception{
System.out.println("登录页面");
// 登录失败从request中获取shiro处理的异常信息。
// shiroLoginFailure:就是shiro异常类的全类名.
String exception = (String) request.getAttribute("shiroLoginFailure");
System.out.println("exception="+exception);
String msg = "";
if (exception!=null){
if (UnknownAccountException.class.getName().equals(exception)){
System.out.println("账号不存在");
msg = "账号不存在";
} else if (IncorrectCredentialsException.class.getName().equals(exception)){
System.out.println("密码不正确");
} else if ("kaptchaValidateFailed".equals(exception)){
System.out.println("验证码不正确");
} else {
msg ="else "+exception;
System.out.println("else "+exception);
}
}
map.put("msg",msg);
return "login";
}
@RequestMapping("/403")
public String unauthorizaRole(){
System.out.println("没有权限");
return "/403";
}
@RequestMapping("/registered")
public String registered(){
return "/registered";
}
}
package com.example.mybatisdemo.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/nofilter")
public class NoFiltercController {
@RequestMapping("/nofilter")
public String nofilter(){
return "static/nofilter";
}
}
在/nofilter下的所有链接都可以匿名访问
package com.example.mybatisdemo.web;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/userInfo")
public class UserInfoController {
@RequestMapping("/userList")
@RequiresPermissions("userInfo:view")
public String userInfo(){
return "userInfo";
}
@RequestMapping("/userAdd")
@RequiresPermissions("userInfo:add")
public String userInfoAdd(){
return "userInfoAdd";
}
@RequestMapping("/userDel")
@RequiresPermissions("UserInfo:del")
public String userInfoDel(){
return "userInfoDel";
}
}
/userinfo下的所有连接都需要验证登陆后实现
除了login.html之外都很简单,贴出login.html和index.html,其他的网页都可以仿照index.html实现
Login
错误信息:
index
index
1、编写好后就可以启动程序,访问http://localhost:8080/userInfo/userList页面,由于没有登录就会跳转到http://localhost:8080/login页面,登陆之后就会跳转到index页面,登录后,直接在浏览器中输入http://localhost:8080/userInfo/userList访问就会看到用户信息。上面这些操作时候触发MyShiroRealm.doGetAuthenticationInfo()
这个方法,也就是登录认证的方法。
2、登录admin账户,访问:http://127.0.0.1:8080/userInfo/userAdd显示用户添加界面
,访问http://127.0.0.1:8080/userInfo/userDel显示403没有权限
。上面这些操作时候触发MyShiroRealm.doGetAuthorizationInfo()
这个方面,也就是权限校验的方法。
3、修改admin不同的权限进行测试
4、登陆http://localhost:8080/druid 可以看到sql语句监控,账号admin密码admin