本文转载自凌大大的博客,原博客地址:[关于用户登录和权限验证功能的实现步骤](https://blog.csdn.net/wohaqiyi/article/details/79338439)
接上一篇文章shiro框架—关于用户登录和权限验证功能的实现步骤(五)
在我前几篇文章里有shiro配置的文件下载包,下载后里边有四个配置文件ShiroConfig
、RetryLimitHashedCredentialsMatcher
、UserRealm
、MShiroFilterFactoryBean
。这四个配置文件,在前边几篇文章里,已经一一写明,还有一个文件,即LoginCheckController
类,这个里边有关于shiro
框架下提供的登录、退出的接口。
具体配置如下:
package microservice.fpzj.shiro.controller;
import microservice.fpzj.control.base.BaseController;
import microservice.fpzj.core.models.Role;
import microservice.fpzj.core.models.User;
import microservice.fpzj.service.jwt.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;@Controller
public class LoginCheckController extends BaseController{private static Logger logger = LoggerFactory.getLogger(LoginCheckController.class);@Autowiredprivate UserService userService;/*** 用户登录验证入口* 1、首次访问全部过滤到/index请求下,因为没有token,进入shiro验证会不通过,则会重定向到远程进行登录* 2、远程登录成功后,根据该处给出的redirect地址,带上token重定向本方法,进行重新验证。* @param* @return*/@RequestMapping(value="/weblogin",method=RequestMethod.GET)public String ssoLoginForm(String httptoken) throws Exception {boolean res=userService.verifyHttpToken(httptoken);if(!res){return "profession/views/login";}String token = userService.getContentFromHttpToken(httptoken);UsernamePasswordToken upt = new UsernamePasswordToken(token,"");Subject subject = SecurityUtils.getSubject();try {subject.login(upt);} catch (Exception e) {return "profession/views/login";}Session session = subject.getSession();session.setAttribute("token", token);String username = userService.getUsernameFromToken(token);User user = userService.findUserByUserName(username);user.setPasswd("");session.setAttribute("sessionUser", user);return "redirect:home";}/*** 跳转本地登录页面*/@RequestMapping(value="/login",method=RequestMethod.GET)public String login(HttpServletRequest request){return "profession/views/login";}/*** 本地登录页面账户密码提交验证* @param request* @return*/@RequestMapping(value="/login",method=RequestMethod.POST)@ResponseBodypublic Object loginForm(HttpServletRequest request) throws Exception {String username = request.getParameter("username");String password = request.getParameter("password");UsernamePasswordToken upt = new UsernamePasswordToken(username,password);Subject subject = SecurityUtils.getSubject();try {subject.login(upt);} catch (Exception e) {if("no_user".equals(e.getMessage())){return addResultMapMsg(false,"当前用户不存在");}if("no_permission".equals(e.getMessage())){return addResultMapMsg(false,"该用户没有当前系统的访问权限");}return addResultMapMsg(false,"账号密码错误");}Session session = subject.getSession();String createToken = userService.createTokenAndSave(username);session.setAttribute("token", createToken);User user = userService.findUserByUserName(username);for (Role r : user.getRoles()) {if (r.getSiteid() == 2) { user.setRole(r);break;}}user.setPasswd("");session.setAttribute("sessionUser", user);return addResultMapMsg(true,"登录成功");}/*** 登录首页* @return*/@RequestMapping(value={"/home","/"},method=RequestMethod.GET)public Object home(){return "profession/views/index";}/*** 本地登出页面* @param redirectAttributes* @return*/@RequestMapping(value="/logout",method=RequestMethod.GET) public String logout(RedirectAttributes redirectAttributes ){ Subject subject = SecurityUtils.getSubject();if (subject.isAuthenticated()) { subject.logout(); }return "profession/views/login";}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
以上有个login
方法,这是一个GET
请求方法,是shiroConfig
类中配置的未登录的情况下跳转的第一个接口,意思是,只要没有登录就会跳转到这个接口。
另外还有个loginForm
方法,是一个POST
请求方法,该方法是登录页面输入账号密码后,请求的登录验证接口,这地方主要有这样一个地方需要注意一下,如下:
UsernamePasswordToken upt = new UsernamePasswordToken(username,password);
Subject subject = SecurityUtils.getSubject();
try {subject.login(upt);} catch (Exception e) {return "profession/views/login";}
以上的UsernamePasswordToken
是用来存放用户名密码的对象,
另外SecurityUtils.getSubject()
,这个特别重要,是shiro
框架中获取的当前访问的用户对象,一个客户端将会对应一个subject
,最后就是subject.login(upt)
该方法,就开始进入到shiro
框架里验证账号密码了,从这里再往后走的逻辑图具体如下:
还有一个地方,即退出的logout
方法,因为退出后,需要清除shiro
框架里记录的用户信息,比如subject
对象,以及其中的session
对象等等,那么就需要该方法里的写法:
Subject subject = SecurityUtils.getSubject()if (subject.isAuthenticated()) { subject.logout()}return "profession/views/login"
以上的方法subject.logout()
即退出,并清除subject
。
以上仅仅是我个人打断点后走过的步骤,个人理解,如果有错误,请留言帮我指正一下,谢谢了。
下一篇文章shiro框架—关于用户登录和权限验证功能的实现步骤(七)