目录
(1) 首先我准备一个数据库 shiro_demo 并且新建了一张bos_user 的表
(2)在pom 文件中引入 Shiro 1.5.2 的jar 包
(6) MyFormAuthenticationFilter
(7) MyHashedCredentialsMatcher
(1) 我编写了俩个接口:一个是test 一个是vueLogin
(3)在网页上访问一下:http://localhost:8006/test/ 鼠标一回车显示的是未登录
前言:
Shiro 安全框架是目前为止作为登录注册最常用的框架,因为它十分的强大简单,提供了认证,授权 ,加密和会话管理等功能。
我们项目的登录功能就集成了Shiro ,如果你也对Shiro感兴趣,一起随着小编看下去吧!
Shiro 官网 :http://shiro.apache.org/
Apache Shiro 1.5.2是当前的稳定版本(Java 1.8+ JVM)。
概念:
图引自:戳这
最简单的Shiro应用:
1.应用代码通过Subject 来进行认证和授权,而Subject 又委托给SecurityManager
2.我们需要给Shiro的SecurityManager 注入Realm,从而让SecurityManager能得到合法的用户及其权限进行判断。
三个核心组件:
Subject, SecurityManager 和 Realms.
①Subject:即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。Subject代表了当前用户的安全操作,SecurityManager则管理所有用户的安全操作。
②SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
③Realm: Realm充当了Shiro与应用安全数据间的“桥梁”或者“连接器”。也就是说,当对用户执行认证(登录)和授权(访问控制)验证时,Shiro会从应用配置的Realm中查找用户及其权限信息。
Shiro登录验证的流程:
- 调用subject.login() 方法进行登录,其会自动委托给securityManager.login方法进行登录。
- 通过SecurityManager进入 realm 中进行判断权限和登录认证
- 在 realm 中调用dao 层查询数据库
- 获取用户数据
- realm 包装原始数据传入SecurityManager。通过SecurityManager调用认证方法,根据login 传入的 token 和 realm 返回的用户真实数据进行比对是否正确。如果不正确抛出各种异常,比如未知用户异常,密码错误,登录次数过多异常等。
- 根据返回的异常,各种 try..catch..,没有异常返回,则表示登录成功,反之返回前端 catch 结果。
Shiro 登录认证过程详解:https://blog.csdn.net/caoyang0105/article/details/82769293
1. Shiro认证目的就是判断用户的账号密码是否正确之类的,授权的作用嘛,简单的解释就是给用户赋予相应的权限。
2. 判断一个用户有没有权限访问,无非是拦截URL能否访问,分为以下几个操作
- 判断当前URL是否需要拦截,不需要则放行,需要则进入下一步
- 判断用户是否已登陆,有则下一步,无则抛出401未认证
- 从资源表/权限表读取当前登陆用户的可访问地址,进入下一步
- 判断是否包含用户当前访问的地址,有则放行,无则抛出403无权限
源码:
链接:https://pan.baidu.com/s/1DxfE-Azg2RZrSS6sDlP59Q
提取码:01z2
同时代码也放入github中,网址:https://github.com/tanghh0410/csdn_blog.git
步骤:
(1) 首先我准备一个数据库 shiro_demo 并且新建了一张bos_user 的表
(2)在pom 文件中引入 Shiro 1.5.2 的jar 包
<!-- shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.5.2</version>
</dependency>
(3) 配置文件中配置数据连接信息
server.port=8006
# MySQL Database
spring.datasource.url=jdbc:mysql://localhost:3306/shiro_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
shiro.jessionid=sessionId
(4)编写Shiro 的配置类
package com.example.shiro.config;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.servlet.HandlerExceptionResolver;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*
*/
@Configuration
public class ShiroConfig {
@Value("${shiro.jessionid}")
private String jessionId;
@Value("${spring.datasource.url}")
public String url;
@Value("${spring.datasource.username}")
public String username;
@Value("${spring.datasource.password}")
public String password;
@Value("${spring.datasource.driver-class-name}")
public String driver;
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
/* 自定义filter注册 */
Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
filters.put("myAuthc", new MyFormAuthenticationFilter());
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//注意过滤器配置顺序 不能颠倒
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/vueLogin", "anon");
filterChainDefinitionMap.put("/**", "myAuthc");
//转应配置shiro默认登录界面地址,前后端分离中登录界面跳由前端路由控制,后台仅返回json数据
shiroFilterFactoryBean.setLoginUrl("/unauth");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public MyRealm realm() {
MyRealm myRealm = new MyRealm();
//验证
MyHashedCredentialsMatcher myHashedCredentialsMatcher = new MyHashedCredentialsMatcher();
myHashedCredentialsMatcher.setHashAlgorithmName("MD5");
myRealm.setCredentialsMatcher(myHashedCredentialsMatcher);
return myRealm;
}
// @Bean
// public JdbcRealm jdbcRealm() {
// JdbcRealm jdbcRealm = new JdbcRealm();
// jdbcRealm.setPermissionsLookupEnabled(true);//为了查询权限表,要开启权限查询
// jdbcRealm.setDataSource(datasource());
// return jdbcRealm;
// }
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm());
// 自定义缓存实现 使用redis
// 自定义session管理
securityManager.setSessionManager(defaultWebSessionManager());
return securityManager;
}
@Bean
public RedisSessionDao getRedisSessionDao() {
return new RedisSessionDao();
}
/**
* @return
* @see DefaultWebSessionManager
*/
@Bean(name = "sessionManager")
public DefaultWebSessionManager defaultWebSessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//sessionManager.setCacheManager(cacheManager());
//12小时
sessionManager.setGlobalSessionTimeout(43200000);
sessionManager.setDeleteInvalidSessions(true);
//关键在这里
sessionManager.setSessionDAO(getRedisSessionDao());
sessionManager.setSessionValidationSchedulerEnabled(true);
sessionManager.setDeleteInvalidSessions(true);
sessionManager.setSessionIdCookie(getSessionIdCookie());
return sessionManager;
}
/**
* 给shiro的sessionId默认的JSSESSIONID名字改掉
*
* @return
*/
@Bean(name = "sessionIdCookie")
public SimpleCookie getSessionIdCookie() {
SimpleCookie simpleCookie = new SimpleCookie(jessionId);
return simpleCookie;
}
/**
* 自定义sessionManager
*
* @return
*/
@Bean
public SessionManager sessionManager() {
MySessionManager mySessionManager = new MySessionManager();
return mySessionManager;
}
/**
* 开启aop注解支持
*
* @param
* @return
*/
@Bean(name = "lifecycleBeanPostProcessor")
public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
/**
* 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
* 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
*
* @return
*/
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
return authorizationAttributeSourceAdvisor;
}
@Bean(name = "exceptionHandler")
public HandlerExceptionResolver handlerExceptionResolver() {
return new MyExceptionHandler();
}
}
(5) 异常处理类 NyExceptionHandler
package com.example.shiro.config;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: tanghh18
* @Date: 2020/4/6 11:28
*/
public class MyExceptionHandler implements HandlerExceptionResolver {
private static Logger logger = LoggerFactory.getLogger(MyExceptionHandler.class);
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
ModelAndView mv = new ModelAndView();
FastJsonJsonView view = new FastJsonJsonView();
Map map = new HashMap();
if (ex instanceof UnauthenticatedException|| ex instanceof IncorrectCredentialsException || ex instanceof AuthenticationException) {
map.put("msg", "用户名或密码错误");
} else if (ex instanceof UnauthorizedException) {
map.put("msg", "无权限");
} else {
map.put("msg", ex.getMessage());
logger.info(ex.getMessage());
ex.printStackTrace();
}
view.setAttributesMap(map);
mv.setView(view);
return mv;
}
}
(6) MyFormAuthenticationFilter
package com.example.shiro.config;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.context.annotation.Bean;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* @Author: tanghh18
* @Date: 2020/4/6 11:29
*/
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
@Override
protected AuthenticationToken createToken(String username, String password, ServletRequest request, ServletResponse response) {
boolean rememberMe = isRememberMe(request);
String host = getHost(request);
String loginType = "password";
if(request.getParameter("loginType")!=null && !"".equals(request.getParameter("loginType").trim())){
loginType = request.getParameter("loginType");
}
return new MyUsernamePasswordToken(username, password,loginType,rememberMe,host);
}
}
(7) MyHashedCredentialsMatcher
package com.example.shiro.config;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
/**
* @Author: tanghh18
* @Date: 2020/4/6 11:30
*/
public class MyHashedCredentialsMatcher extends HashedCredentialsMatcher {
@Override public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
MyUsernamePasswordToken mupt = (MyUsernamePasswordToken)token;
if ("nopassword".equals(mupt.getLoginType())) {
return true;
}else {
return super.doCredentialsMatch(token, info);
}
}
}
(8) MyRealm
package com.example.shiro.config;
import com.example.model.BosUserModel;
import com.example.service.BosUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Author: tanghh18
* @Date: 2020/4/6 11:34
*/
public class MyRealm extends AuthorizingRealm {
@Autowired
BosUserService bosUserService;
/**
* 授权
*
* @param principals
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
/**
* 认证
*
* @param arg0
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
//将父类的AuthenticationToken强转为UsernamePasswordToken(因为需要调用UsernamePasswordToken的方法)
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) arg0;
//获取用户名
String uname = usernamePasswordToken.getUsername();
//模拟通过数据库查询到用户名的密码
BosUserModel user = bosUserService.findUserModelByName(uname);
//认证信息(参数填写的是用户输入的用户名和数据库查询的密码)
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(uname, user.getPassword(), getName());
return info;
}
}
(9) MySessionManager
package com.example.shiro.config;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
/**
* @Author: tanghh18
* @Date: 2020/4/6 14:00
*/
public class MySessionManager extends DefaultWebSessionManager {
private static final String AUTHORIZATION = "Authorization";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
public MySessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
//如果请求头中有 Authorization 则其值为sessionId
if (!StringUtils.isEmpty(id)) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
} else {
//否则按默认规则从cookie取sessionId
return super.getSessionId(request, response);
}
}
}
(10) MyUserNamePasswordToken
package com.example.shiro.config;
import org.apache.shiro.authc.UsernamePasswordToken;
/**
* @Author: tanghh18
* @Date: 2020/4/6 14:00
*/
public class MyUsernamePasswordToken extends UsernamePasswordToken {
/**
* 免密登录/账号密码登录
*/
private String loginType;
public MyUsernamePasswordToken() {
super();
}
/**
* 账号密码登录
* @param username
* @param password
* @param loginType
* @param rememberMe
* @param host
*/
public MyUsernamePasswordToken(String username, String password, String loginType, boolean rememberMe, String host) {
super(username, password, rememberMe, host);
this.loginType = loginType;
}
/**
* 免密登录
* @param username
*/
public MyUsernamePasswordToken(String username) {
super(username, "", false, null);
this.loginType = "nopassword";
}
public MyUsernamePasswordToken(String username, String password) {
super(username, password, false, null);
this.loginType ="password";
}
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
}
(11)RedisSessionDao
package com.example.shiro.config;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Created by Administrator on 2018/7/31.
*/
@Service
public class RedisSessionDao extends AbstractSessionDAO {
/**
* Session超时时间,单位为毫秒
*/
private static Logger logger = LoggerFactory.getLogger(RedisSessionDao.class);
private long expireTime = 30*60*1000;
/**
* Redis操作类,对这个使用不熟悉的,可以参考前面的博客
*/
@Autowired
private RedisTemplate redisTemplate;
public RedisSessionDao() {
super();
}
public RedisSessionDao(long expireTime, RedisTemplate redisTemplate) {
super();
this.expireTime = expireTime;
//Long类型不可以会出现异常信息;
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
this.redisTemplate = redisTemplate;
}
/**
* 更新session
* @param session
* @throws UnknownSessionException
*/
@Override
public void update(Session session) throws UnknownSessionException {
if (session == null || session.getId() == null) {
return;
}
session.setTimeout(expireTime);
redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
}
/**
* 删除session
* @param session
*/
@Override
public void delete(Session session) {
if (null == session) {
return;
}
redisTemplate.opsForValue().getOperations().delete(session.getId());
}
/**
* // 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,
* 可以在将session加入redis时指定一个session前缀,统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合
* @param
* @return
*/
@Override
public Collection<Session> getActiveSessions() {
Set keys = redisTemplate.keys("*");
Collection<Session> activeSessions = new ArrayList<>();
for (Object o:keys){
String sessionId = o.toString();
if(sessionId.equals("SuiteTicket") || sessionId.equals("suite_access_token")){
continue;
}
Session session = (Session) redisTemplate.opsForValue().get(sessionId);
activeSessions.add(session);
}
return activeSessions;
}
/**
* 加入session
* @param session
* @return
*/
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
//Long类型不可以会出现异常信息;
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
return sessionId;
}
/**
* 读取session
* @param sessionId
* @return
*/
@Override
protected Session doReadSession(Serializable sessionId) {
if (sessionId == null) {
return null;
}
return (Session) redisTemplate.opsForValue().get(sessionId);
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
//Long类型不可以会出现异常信息;
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
this.redisTemplate = redisTemplate;
}
}
(12)整个项目路径是这样的!
测试:
(1) 我编写了俩个接口:一个是test 一个是vueLogin
package com.example.controller;
import com.example.model.BosUserModel;
import com.example.service.BosUserService;
import com.example.shiro.config.MyUsernamePasswordToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: wwc
* @Date: 2019/3/6 14:26
* @Version 1.0
*/
@RestController
public class ShiroController {
@Autowired
private BosUserService bosUserService;
@GetMapping(value = "/test")
public void test(){
System.out.println("这是测试接口-----");
}
/**
* 登录方法
*
* @return
*/
@GetMapping(value = "/vueLogin")
public void login(HttpSession session) throws Exception {
//shiro登录,普通的用户名和密码登录
Subject subject = SecurityUtils.getSubject();
BosUserModel user = new BosUserModel();
user.setId(1);
user.setUserName("soup_tang");
user.setPassword("1");
// user.setPassword("c4ca4238a0b923820dcc509a6f75849b");
UsernamePasswordToken token = new MyUsernamePasswordToken(user.getUserName(), user.getPassword());
subject.login(token);
//用户数据保存到session里
BosUserModel bosUserModel = bosUserService.findUserModelByName(user.getUserName());
if(bosUserModel!=null){
System.out.println("登录成功");
session.setAttribute("user", bosUserModel);
}else{
System.out.println("登录失败");
}
}
/**
* 未登录,shiro应重定向到登录界面,此处返回未登录状态信息由前端控制跳转页面
*
* @return
*/
@RequestMapping(value = "/unauth")
@ResponseBody
public Object unauth() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("msg", "未登录");
return map;
}
}
(2)业务逻辑类如下:
package com.example.service.impl;
import com.example.model.BosUserModel;
import com.example.service.BosUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;
/**
* @Author tanghh
* @Date 2020/4/6 10:49
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class BosUserServiceImpl implements BosUserService {
@Autowired
private JdbcTemplate jdbcTemplate;
/**
* 根据名字查询用户数据
* @param name
* @return
*/
@Override
public BosUserModel findUserModelByName(String name) {
String sql = "select * from bos_user where user_name=?";
Map map = new HashMap<>();
map.put("name",name);
BosUserModel userModel = this.jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<BosUserModel>(BosUserModel.class),name);
return userModel;
}
}
(3)在网页上访问一下:http://localhost:8006/test/ 鼠标一回车显示的是未登录
(4)在网页上访问一下:http://localhost:8006/vueLogin/
控制台打印语句:
一个接口test 被拦截了 , 一个vueLogin没有被拦截,那么是通过什么方法被拦截的呢?答案在:ShiroConfig类。
我在下面这个类的位置 配置了 vueLogin 不被拦截。
还有一个问题就是:
可以看到下面这张图我将 密码写成的是md5加密的值,这个时候会出现什么问题呢,往下看:
在我的 MyExceptionHandler 类开始报异常了。
百度一下结果 是因为传过来的密码无法将值hash ,后面将代码改过来就可以了,因为我在下面这个方法中写了将密码转化成md5
使用: user.setPassword("1");
参考文章:
Shiro学习目录贴:https://www.iteye.com/blog/jinnianshilongnian-2018398