【问题标题】:Shiro with HTTP Basic Auth or Anonymous access to same URI具有 HTTP 基本身份验证或匿名访问相同 URI 的 Shiro
【发布时间】:2014-10-13 01:15:50
【问题描述】:

我在 /api 下有一组 API。如果我的 shiro.ini 将其列为:

/api/** = authcBasic

然后需要基本身份验证。如果 anon 代替 authcBasic,则不需要 auth。我希望能够使用具有基本身份验证的 API,以便我可以例如以编程方式检查用户是否已通过 POST 身份验证,但仍允许匿名访问同一 URI 上的 GET。或者,为匿名用户隐藏同一 URI 中的受限数据,并为经过身份验证的用户显示。

这可能吗?

【问题讨论】:

    标签: java authentication basic-authentication shiro


    【解决方案1】:

    您可以滚动您自己的自定义 shiro 过滤器。扩展类 BasicHttpAuthenticationFilter 并覆盖 onPreHandle,您可以在其中检查 servlet 请求方法是 GET 还是 POST 并对其进行操作。

    比如:

    public class MyFilter extends BasicHttpAuthenticationFilter {
    
        @Override
        protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {
            if ("GET".equals((HttpServletRequest)request).getMethod()){
                return true;
            }
            return super.onPreHandle(request, response, mappedValue);
        }
    
    }
    

    在 shiro.ini 中:

    [main]
    myfilter = mypackage.MyFilter
    
    [urls]
    /api/** = myfilter
    

    【讨论】:

    • 我不确定这是否有效 - 它允许访问,但是当提供基本身份验证凭据时,当前主题似乎没有经过身份验证。即使调用 super.isAccessAllowed() 也是如此,但不管它是否是 GET 请求,都会返回 true。
    • 我认为您应该使用onPreHandle,这与匿名过滤器使用的相同。改变了答案
    • 我想我不太明白。您是否通过 POST(基本身份验证)获得了正确的行为,但 GET 上的匿名访问不起作用?
    • 它确实可以将身份验证限制为 POST,是的。但是我仍然需要允许针对 GET 进行身份验证,这样我就可以向这些用户显示他们有权查看的额外数据,如果没有提供身份验证,则可以退回到仅显示公共数据。这种方式似乎不接受基本身份验证作为 GET 请求的选项,它只是匿名访问。是不是更清楚了?
    • 是的,我现在明白了。我认为您最好拆分可以匿名访问的特定网址,并在其余所有网址上进行基本身份验证。所以 /api/public/** = anon /api/** = authcBasic。为什么此设置不适合您?
    【解决方案2】:

    你试过了吗:

    /api/** = authcBasic[permissive]

    • 如果设置了用户/密码,如果错误,shiro 发送 401
    • 如果未设置用户/密码,则没有 401。SecurityUtils.getSubject().authenticated 为 false

    【讨论】:

      【解决方案3】:

      我认为这行得通。

          @Override
      protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
          boolean loggedIn = false; //false by default or we wouldn't be in this method
          if (isLoginAttempt(request, response)) {
              loggedIn = executeLogin(request, response);
          }
          if (!loggedIn) {
      //            sendChallenge(request, response);
                  return true;
          }
          return loggedIn;
      }
      

      即如果提供了授权详细信息,则正常执行登录(如果授权详细信息无效,则为 401),否则无论如何都允许它们(然后检查是否经过身份验证,稍后授权)。

      这个方法有一个警告,虽然它适用于 curl 测试,但使用 Apache 的 HttpClient Fluent API 似乎会在未经授权的情况下发送请求,然后在质询响应后发送带有凭据的第二个请求,这显然是现在不发送。可以说是 HttpClient 中的一个错误,但看到我们可能已经偏离了基本的身份验证规范,它可能需要它。所以YMMV。这可以通过使用抢占式身份验证并将标头值指定为suggested here 来解决。

      【讨论】:

        猜你喜欢
        • 2014-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多