使用shiro与stormpath进行jax-rs rbac

时间:2017-01-29 18:59:26

标签: jersey jax-rs shiro stormpath

我试图根据我自己的目的调整这个优秀的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://....

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

2 个答案:

答案 0 :(得分:1)

感谢您阅读该帖子!

我想指出几件事:

  • 使用此功能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,我们会帮你的!

答案 1 :(得分:0)

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

我在shiro网站上关注了这个网络应用教程。

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

我检查了项目的第6步并复制了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的自定义数据 - 我添加了一个字符串键/值对&#39; trooper:read&#39;到apacheShiroPermissions - JSON在

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

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

使用curl进行测试

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

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

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

毫无疑问,这是一种更好的方法,但到目前为止,这对我有用。