yangyang12138

导航

shrio

1.概述

  一个基于token的权限认证组件,适用于api和web两种场景。

2.使用demo

  配置三个filter,全局filter用于组织没有权限的请求,apiLoginFilter用于处理api的登录请求,uiLoginFilter用于处理来自界面的登录请求。

  1).全局filter

public class GlobalFilter extends FormAuthenticationFilter {
    Logger log = LoggerFactory.getLogger(GlobalFilter.class);
    private AntPathMatcher antPathMatcher =new AntPathMatcher();

    private static final Logger _logger = LoggerFactory.getLogger(GlobalFilter.class);


    protected void issueSuccessRedirect(ServletRequest request, ServletResponse response) throws Exception {
        WebUtils.issueRedirect(request, response, "/", null, true);
    }
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {return super.preHandle(request, response);
    }
    //保存异常对象到request
    @Override
    protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
        request.setAttribute(getFailureKeyAttribute(), ae);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        boolean isAccessAllowed=false;
         Subject subject = getSubject(request, response);
         HttpServletRequest req = (HttpServletRequest) request;
         String requestURI = req.getRequestURI();
         if(antPathMatcher.match("/webui/login",requestURI)||antPathMatcher.match("/api/login",requestURI)){//排除登录请求
             return true;
         }
         return subject.isAuthenticated();
    }

}

对于没有权限的请求默认是跳转到登录页,如果不需要跳转而是返回异常或是别的处理可以重载onAccessDenied。

  2).apiLoginFilter

public class ApiLoginFilter extends BasicHttpAuthenticationFilter{
    Logger log = LoggerFactory.getLogger(ApiLoginFilter.class);
    private AntPathMatcher antPathMatcher =new AntPathMatcher();

    @Override
    protected boolean isLoginAttempt(ServletRequest request, ServletResponse response) {
        HttpServletRequest req = (HttpServletRequest) request;
        String authorization = req.getHeader("Authorization");return authorization == null;
    }

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String requestURI = httpServletRequest.getRequestURI();

        String authorization = httpServletRequest.getHeader("Authorization");

        JwtToken token = new JwtToken(authorization);

        getSubject(request, response).login(token);

        return true;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginAttempt(request, response)) {
            try {
                executeLogin(request, response);
            } catch (Exception e) {
                e.printStackTrace();
                response401(request, response);
            }
        }
        HttpServletRequest req = (HttpServletRequest) request;
        String requestURI = req.getRequestURI();

        Subject subject = getSubject(request, response);
        return subject.isAuthenticated();
    }
}

另外需要设置一个realm来完成真正登录逻辑,

public class SelfRealm extends AuthorizingRealm {

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

      String token
= (String) authenticationToken.getCredentials(); // 解密获得username,用于和数据库进行对比 if(token!=null&&!"".equals(token.trim())){ String username = JWTUtil.getUsername(token); if (username == '123') {
      return new SimpleAuthenticationInfo(user, user.getPassword(), "self");
     }
      
return null; } }

3.shiro结构

  

 

  以上为shiro的核心实现,web层认证只是向web的Filter中做了适配。

 

posted on 2020-07-24 00:48  杨杨09265  阅读(262)  评论(0编辑  收藏  举报