Shrio是一个轻量级的,基于AOP 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同时在 Web 请求级和方法调用级处理身份确认和授权。

JWT(JSON Web Token)是目前最流行的跨域身份验证解决方案,具有加密和自包含的特性。

1.maven配置

<!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.2.0</version>
        </dependency>

 

2.自定义Token Authentication

package com.bby.security;

import org.apache.shiro.authc.AuthenticationToken;

/**
 * 自定义jwt类型的token
 *
 * @author: zhangyang
 * @create: 2018/11/28 8:39
 **/
public class MyJWTToken implements AuthenticationToken {
    private String token;

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

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

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

 

3.自定义Shiro过滤器

package com.bby.security;

import com.alibaba.fastjson.JSONObject;
import com.bby.common.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;


/**
 * jwt token filter
 *
 * @Author zhangyang
 * @Date 下午 8:42 2018/11/27 0027
 **/
@Slf4j
public class MyJWTFilter extends BasicHttpAuthenticationFilter {

    private String tokenHeader;
    private String loginUri;

    public MyJWTFilter(String tokenHeader, String loginUri) {
        this.tokenHeader = tokenHeader;
        this.loginUri = loginUri;
    }

    /**
     * 如果是登录则直接放行;
     * 如果带有 token,则对 token 进行检查
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        HttpServletRequest req = (HttpServletRequest) request;
        AntPathMatcher matcher = new AntPathMatcher();
        // 开放登录接口访问
        if (matcher.match(loginUri, req.getRequestURI())) {
            return true;
        }
        // 判断请求的请求头是否带上token
        if (StringUtils.isBlank(req.getHeader(tokenHeader))) {
            return false;
        }

        // 如果存在,则进入 executeLogin 方法执行登入,检查 token 是否正确
        try {
            executeLogin(request, response);
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                // globalExceptionHandler无法处理filter中的异常,这里手动处理
                PrintWriter out = response.getWriter();
                out.print(JSONObject.toJSON(Result.failureWithCode(Result.UNAUTHORIZED, e.getMessage())));
                out.flush();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return false;
        }
        return true;
    }

    /**
     * 执行登陆操作
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String token = httpServletRequest.getHeader(tokenHeader);
        MyJWTToken jwtToken = new MyJWTToken(token);
        // 提交给realm进行登入,如果错误他会抛出异常并被捕获
        getSubject(request, response).login(jwtToken);
        // 如果没有抛出异常则代表登入成功,返回true
        return true;
    }
}
View Code

相关文章:

  • 2021-09-05
  • 2021-10-09
  • 2021-12-08
  • 2021-07-30
  • 2021-11-22
  • 2021-06-18
猜你喜欢
  • 2021-10-21
  • 2022-02-09
  • 2021-08-20
  • 2021-04-27
  • 2019-07-30
  • 2022-12-23
相关资源
相似解决方案