【问题标题】:using shiro with stormpath for jax-rs rbac将 shiro 与 Stormpath 一起用于 jax-rs rbac
【发布时间】:2017-06-14 22:49:47
【问题描述】:

我正在尝试调整 Brian Demers 的这篇出色的 Stormpath 帖子 - https://stormpath.com/blog/protecting-jax-rs-resources-rbac-apache-shiro - 以适应我自己的目的,到目前为止它运行良好 - 除了现在我想为用户/角色管理添加 Stormpath 而不是拥有shiro-ini 文件中的用户。

我正在使用 Apache Shiro shiro-jaxrs 1.4.0-RC 来保护使用 jax-rs 的 REST 端点。它工作正常。我可以使用 @RequiresPermissions 标记有选择地保护端点,如下所示:

@Path("/scan")
@Produces("application/json")
public class ScanService {

final static Logger logger = Logger.getLogger(ScanService.class);

@GET
@Path("/gettest")
@RequiresPermissions("troopers:read")
public List<Barcode> gettest() throws Exception {

ArrayList<Barcode> listofstrings = new ArrayList<Barcode>();
    Barcode b = new Barcode();
    b.setBarcode("this is a big barcode");
    listofstrings.add(b );

    return listofstrings;

}


@GET
@Produces( MediaType.APPLICATION_JSON  )
@Path("/gettest2")
public List<Barcode> gettest2() throws Exception {
    ArrayList<Barcode> listofstrings = new ArrayList<Barcode>();
    Barcode b = new Barcode();
    b.setBarcode("this is a BIGGER barcode");
    listofstrings.add(b );

    return listofstrings;
}

我还有一个应用程序类来添加我的资源和 ShiroFeature 类,如下所示:

package ca.odell.erbscan;
import ca.odell.erbscan.ws.ScanService;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.web.jaxrs.ShiroFeature;
import com.stormpath.shiro.jaxrs.StormpathShiroFeature;


@ApplicationPath("/")
public class ERBApplication extends Application {

@Override
public Set<Class<?>> getClasses() {
    Set<Class<?>> classes = new HashSet<Class<?>>();

    // register Shiro
    classes.add( ShiroFeature.class);
    // register resources
    classes.add(ScanService.class);

    return classes;
}
}

和我的 web.xml 像这样初始化我的 Application 类:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>ERBSCAN</display-name>
<servlet>


    <servlet-name>ERBRest</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>ca.odell.erbscan</param-value>
    </init-param>

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>ca.odell.erbscan.ERBApplication</param-value>
    </init-param>


    <load-on-startup>1</load-on-startup>
</servlet>



<servlet-mapping>
    <servlet-name>ERBRest</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>


</web-app>

最后是我的 shiro.ini

[main]



cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager



sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.sessionIdCookieEnabled = false
securityManager.sessionManager.sessionIdUrlRewritingEnabled = false


[urls]
/** = noSessionCreation, authcBasic[permissive]

[users]
# format: username = password, role1, role2, ..., roleN
root = secret,admin
emperor = secret,admin
officer = secret,officer
guest = secret

[roles]

admin = *
officer = troopers:create, troopers:read, troopers:update

我接下来要做的是为 RBAC 添加 Stormpath,而不是在文件中包含用户和角色。我的感觉是有一种简单的方法可以做到这一点,但我想多了。

我认为在我的 shiro.ini 中添加会是一种相当简单的方式:

stormpathClient = com.stormpath.shiro.client.ClientFactory
stormpathClient.cacheManager = $cacheManager

stormpath.application.href=http://....

但我错了。有人能指出我正确的方向吗?

【问题讨论】:

    标签: jersey jax-rs shiro stormpath


    【解决方案1】:

    我将在这里回答我自己的问题。我认为这不是最好的解决方案,但我设法开始工作。

    我在 shiro 网站上遵循了这个网络应用教程。

    https://shiro.apache.org/webapp-tutorial.html

    我检查了项目的 step6 并复制了 shiro.ini 的 [main] 部分,如下所示:注意我添加了

    https://api.stormpath.com/v1/applications/$STORMPATH_APPLICATION_ID

    在 [main] 部分的底部。

    cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
    securityManager.cacheManager = $cacheManager
    
    stormpathClient = com.stormpath.shiro.client.ClientFactory
    stormpathClient.cacheManager = $cacheManager
    
    # we can disable session tracking completely, and have Stormpath manage        it for us.
    sessionManager =   org.apache.shiro.web.session.mgt.DefaultWebSessionManager
    securityManager.sessionManager = $sessionManager
    securityManager.sessionManager.sessionIdCookieEnabled = false
    securityManager.sessionManager.sessionIdUrlRewritingEnabled = false
    
    stormpathRealm = com.stormpath.shiro.realm.ApplicationRealm
    stormpathRealm.client = $stormpathClient
    
    stormpathRealm.groupRoleResolver.modeNames = name
    securityManager.realm = $stormpathRealm
    
    stormpathRealm.applicationRestUrl = https://api.stormpath.com/v1/applications/$STORMPATH_APPLICATION_ID
    

    然后我完全删除了 shiro.ini 的 [users] 部分。由于它现在连接到 Stormpath,我需要在那里添加用户和组。我的 ScanService (如上)有一个名为 gettest 的方法,因此装饰:

    @GET
        @Path("/gettest")
        @RequiresPermissions("trooper:read")
        public List<Barcode> gettest() throws Exception {
    .
    .
    .
    

    所以我需要在stormpath中添加一个帐户、一个组和权限,以匹配上述资源的权限。为此,我需要在我现有的测试应用程序下的 Stormpath 中添加一个帐户(我已经有应用程序设置)。我还添加了一个名为officer1 的组。在这个组下,我添加了自定义数据一个名为 apacheShiroPermissions 的数组 - 我向 apacheShiroPermissions 添加了一个字符串键/值对“trooper:read”——JSON 在下面

    {
      "apacheShiroPermissions": [
        "trooper:read"
      ]
    }
    

    然后我只是确保我的帐户 - 在这种情况下,jlpicard 是officer1 组的一部分。

    用 curl 测试

    curl --user jlpicard:Changeme1 http://localhost:8080/JPA1_Web_exploded/rest/scan/gettest
    

    确认 jlpicard 在权限级别上具有访问权限。在 apacheShiroPermission 数组中添加和删除字符串条目,即允许细粒度访问。

    从officer1 中删除jlpicard 或向其添加另一个帐户也可以按预期工作。

    毫无疑问,有更好的方法可以做到这一点,但这对我来说到目前为止是有效的。

    【讨论】:

      【解决方案2】:

      感谢您阅读这篇文章!

      我想指出几点:

      • 使用此功能com.stormpath.shiro.jaxrs.StormpathShiroFeature 而不是ShiroFeature
      • 您的 shiro.ini 可能类似于:
      [main]
      cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
      securityManager.cacheManager = $cacheManager
      
      sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
      securityManager.sessionManager = $sessionManager
      securityManager.sessionManager.sessionIdCookieEnabled = false
      securityManager.sessionManager.sessionIdUrlRewritingEnabled = false
      
      [urls]
      /** = noSessionCreation, authcBasic[permissive]
      
      [stormpath]
      stormpath.application.href=http://....
      
      • 权限可以存储为用户或角色自定义数据,您可以在 Stormpath 管理控制台中更新自定义数据:
      {
          … your other custom data fields …,
          "apacheShiroPermissions": [
              "troopers:create",
              "troopers:read",
              "troopers:update"
          ]
      }
      

      这个blog post 涵盖了自定义数据位,它有点旧,但仍然相关。我会在不久的将来更新这方面的文档,欢迎反馈。

      如果这没有帮助,你也可以 ping support,我们会帮你的!

      【讨论】:

        猜你喜欢
        • 2019-04-15
        • 2012-11-02
        • 1970-01-01
        • 1970-01-01
        • 2014-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-12
        相关资源
        最近更新 更多