跳至主要內容

springboot整合shiro实现简单的登录

xw大约 3 分钟SpringJavaSpring Boot

shiro核心知识

  • 什么是身份认证
    • Authentication,身份证认证,一般就是登录
  • 什么是授权
    • Authorization,给用户分配角色或者访问某些资源的权限
  • 什么是会话管理
    • Session Management, 用户的会话管理员,多数情况下是web session
  • 什么是加密
    • Cryptography, 数据加解密,比如密码加解密等

shiro常见名称讲解

  • Subject

    • 我们把用户或者程序称为主体(如用户,第三方服务,cron作业),主体去访问系统或者资源
  • SecurityManager

    • 安全管理器,Subject的认证和授权都要在安全管理器下进行
  • Authenticator

    • 认证器,主要负责Subject的认证
  • Realm

    • 数据域,Shiro和安全数据的连接器,好比jdbc连接数据库; 通过realm获取认证授权相关信息
  • Authorizer

    • 授权器,主要负责Subject的授权, 控制subject拥有的角色或者权限
  • Cryptography

    • 加解密,Shiro的包含易于使用和理解的数据加解密方法,简化了很多复杂的api
  • Cache Manager

    • 缓存管理器,比如认证或授权信息,通过缓存进行管理,提高性能

springboot整合shiro

  1. 引入maven依赖

2、自定义realm


package com.xw.shirostudy.shiro;

import com.xw.shirostudy.model.User;
import com.xw.shirostudy.repository.UserRepository;
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;

/**
 * @Description TODO
 */
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    private UserRepository userRepository;

    /**
     * 获取用户角色和权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        return null;
    }

    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        System.out.println("用户" + userName + "认证-----ShiroRealm.doGetAuthenticationInfo");
        User user = userRepository.findUserByUserName(userName);

        if (user == null) {
            throw new UnknownAccountException("用户名或密码错误!");
        }
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException("用户名或密码错误!");
        }
        if (user.getStatus().equals("0")) {
            throw new LockedAccountException("账号已被锁定,请联系管理员!");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }
}

登录验证源码分析

认证流程解读:subject.login(usernamePasswordToken);
	DelegatingSubject->login()
	DefaultSecurityManager->login()
	AuthenticatingSecurityManager->authenticate()
	AbstractAuthenticator->authenticate()
	ModularRealmAuthenticator->doAuthenticate()
	ModularRealmAuthenticator->doSingleRealmAuthentication()
	AuthenticatingRealm->getAuthenticationInfo()

1、首先将输入的账号密码生成UsernamePasswordToken对象,然后获取Subject对象,调用login方法。

 UsernamePasswordToken token = new UsernamePasswordToken(username, password);
 Subject subject = SecurityUtils.getSubject();
 subject.login(token);

2、DelegatingSubject->login()
image.png

3、DefaultSecurityManager->login()
image.png
4、 AbstractAuthenticator->authenticate()

image.png
5、ModularRealmAuthenticator->doAuthenticate()
ModularRealmAuthenticator->doSingleRealmAuthentication()
image.png

6、最后到AuthenticatingRealm->doGetAuthenticationInfo()调自己实现的realm。
image.png

总结

  • shiro的流程控制是基于异常实现,提供了丰富的异常机制。
  • 我们只需要关注业务逻辑进行开发,shiro已经提供良好的封装。

完整代码链接open in new window

TIPS:❤️ debug流程走一遍加深理解哦