Shiro 登录

本文详细描述了用户登录过程中,如何通过Oauth2Filter和Oauth2Realm进行身份验证,包括createToken方法的调用、SecurityManager处理AuthenticationToken、以及Shiro进行身份比对的过程。特别关注了token验证和部分URL的免验证配置。
摘要由CSDN通过智能技术生成

用户尝试登录: 用户提供用户名和密码(或其他身份信息)尝试登录应用程序。

AuthenticatingFilter 的 createToken 方法: 当用户提交登录请求时,与登录相关的过滤器,比如你的 Oauth2Filter 中的 createToken 方法被调用。在这个方法中,创建了 AuthenticationToken 对象(这里是 Oauth2Token),并将其返回。

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
        //获取请求token
        String token = getRequestToken((HttpServletRequest) request);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        return new Oauth2Token(token);
    }
public class Oauth2Token implements AuthenticationToken {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String token;

    public Oauth2Token(String token) {
        this.token = token;
    }

    @Override
    public String getPrincipal() {
        return token;
    }

    @Override
    public Object getCredentials() {
        return token;
    }
}

SecurityManager 调用 Realm 的 doGetAuthenticationInfo 方法: Shiro 的 SecurityManager 接收到 AuthenticationToken 对象后,会调用配置的 Realm 的 doGetAuthenticationInfo 方法,传递 AuthenticationToken 给 Realm。这时,Oauth2Realm 中的 doGetAuthenticationInfo 方法被调用。

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String accessToken = (String) token.getPrincipal();
        String userId = null;
        try {
            userId = jwtUtil.getUserId(accessToken);
        } catch (Exception ex) {
            throw new AuthenticationException("Token失效,请重新登录!");
        }
        //查询用户信息
        SysUserEntity user = shiroService.queryUser(userId);
        if (user != null) {
            //账号锁定
            if (user.getStatus() == 0) {
                throw new LockedAccountException("账号已被锁定,请联系管理员");
            }
        }
        return new SimpleAuthenticationInfo(user, accessToken, getName());
    }

Realm 中执行身份认证逻辑: 在 Oauth2Realm 的 doGetAuthenticationInfo 方法中,你可以编写自定义的身份认证逻辑,例如验证用户名和密码是否匹配,检查用户是否被锁定等。

返回 AuthenticationInfo 对象: 在 doGetAuthenticationInfo 方法中,你需要创建并返回一个 AuthenticationInfo 对象,其中包含了用户的身份信息。通常,你会返回一个 SimpleAuthenticationInfo 对象,其中包括认证成功的用户对象以及用于后续身份验证的凭证信息(例如密码或令牌)。

Shiro 进行身份验证: Shiro 将获得的 AuthenticationInfo 与用户提供的身份信息进行比对,如果匹配,则认为用户通过了身份验证。

方法调用顺序 :

Oauth2Filter.isAccessAllowed  (请求方法类型 是否为 OPTION)   如果返回true,则跳过token 验证,执行api。 如果返回false,则需要验证token。

Oauth2Filter.onAccessDenied (如果token 为空,直接返回401 报错 。) 如果token 不为空,执行executeLogin 方法,其中会调用Oauth2Filter.createToken,然后调用subject.login方法,其中会调用Oauth2Realm.doGetAuthenticationInfo 。 

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        log.info("step : Oauth2Filter.isAccessAllowed");
        // 请求方法类型是否为OPTION,如果是,则跳过token的解析校验
        return ((HttpServletRequest) request).getMethod().equals(RequestMethod.OPTIONS.name());
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        log.info("step : Oauth2Filter.onAccessDenied");
        //获取请求token,如果token不存在,直接返回401
        String token = getRequestToken((HttpServletRequest) request);
        if (StringUtils.isBlank(token)) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
            String json = new Gson().toJson(RestResponse.error(401, "invalid token"));
            httpResponse.getWriter().print(json);
            return false;
        }
        // 调用 createToken 和 Oauth2Realm的doGetAuthenticationInfo
        Boolean flag = executeLogin(request, response);
        return flag;
    }

ShiroConfig 
配置哪些url 不需要经过验证

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);

        //oauth过滤
        Map<String, Filter> filters = new HashMap<>(16);
        filters.put("oauth2", new Oauth2Filter());
        shiroFilter.setFilters(filters);
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/sys/login", "anon");
        filterMap.put("/sys/tyyw/login", "anon");
        filterMap.put("/**", "oauth2");
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值