簡體   English   中英

球衣安全和會話管理

[英]jersey security and session management

有沒有辦法在Jersey中以編程方式獲得會話管理或安全性,例如Web應用程序會話管理? 或者,事務,會話和安全性是否都由部署Jersey應用程序的容器處理?

會話管理是部署Jersey的容器的范圍。 在大多數生產案例中,它將部署在執行會話管理的容器中。

下面的代碼是一個簡單的球衣資源示例,它獲取會話對象並在會話中存儲值並在后續調用中檢索它們。

@Path("/helloworld")
public class HelloWorld {

    @GET
    @Produces("text/plain")
    public String hello(@Context HttpServletRequest req) {

        HttpSession session= req.getSession(true);
        Object foo = session.getAttribute("foo");
        if (foo!=null) {
            System.out.println(foo.toString());
        } else {
            foo = "bar";
            session.setAttribute("foo", "bar");
        }
        return foo.toString();


    }
}

我認為,會議是我們永遠不應該在RESTful應用程序使用...

葉戈爾是對的。 在服務器端一拉傳統的Web應用程序,我們不應該永遠保持狀態。 如果要構建一個分離的面向SOA的應用程序,則不需要使用任何API /框架來進行REST Web服務。 如果您需要或希望在服務器端維護全局客戶端 - 服務器狀態,那么您將隱式構建我們可以描述為面向SOA的[Web]應用程序,但是使用Jersey就像[web]開發框架一樣。 無意中,您正在扭曲Web服務(REST或其他)的本質。 可以按照第一個答案中建議的方式進行,但您不能這樣做 最終結果不是Web服務,只是使用Web服務工具構建的常規應用程序。

-_o

是的,這是可能的。 澤西文件說:

通過使用@Context注釋注入JAX-RS SecurityContext實例,可以獲得請求的安全信息。 注入的安全上下文實例提供HttpServletRequest API上可用功能的等效項。 注入的安全上下文取決於實際的Jersey應用程序部署。 例如,對於部署在Servlet容器中的Jersey應用程序,Jersey SecurityContext將封裝來自從Servlet請求檢索的安全上下文的信息。 如果在Grizzly服務器上部署了Jersey應用程序,SecurityContext將返回從Grizzly請求中檢索到的信息。

例:

@Path("basket")
public ShoppingBasketResource get(@Context SecurityContext sc) {
    if (sc.isUserInRole("PreferredCustomer") {
        return new PreferredCustomerShoppingBasketResource();
    } else {
        return new ShoppingBasketResource();
    }
}

要么

@Path("resource")
@Singleton
public static class MyResource {
    // Jersey will inject proxy of Security Context
    @Context
    SecurityContext securityContext;

    @GET
    public String getUserPrincipal() {
        return securityContext.getUserPrincipal().getName();
    }
}

或者,如果您想要開箱即用的安全注釋,請檢查這些文檔

Jersey還允許您自定義SecurityContext:

可以通過getSecurityContext()方法從ContainerRequestContext直接檢索SecurityContext。 您還可以使用setSecurityContext(SecurityContext)方法將請求上下文中的默認SecurityContext替換為自定義SecurityContext。 如果在ContainerRequestFilter中設置自定義SecurityContext實例,則此安全上下文實例將用於注入JAX-RS資源類字段。 這樣,您就可以實現自定義身份驗證篩選器,該篩選器可以設置您自己的SecurityContext以供使用。 要確保提前執行自定義身份驗證請求篩選器,請使用“優先級”中的常量將篩選器優先級設置為AUTHENTICATION。 早期執行身份驗證篩選器將確保所有其他篩選器,資源,資源方法和子資源定位器將與您的自定義SecurityContext實例一起執行。

請參閱有關如何使用Jersey的請求過濾器的示例 並查看以下示例:

import javax.annotation.Priority;
import javax.ws.rs.Priorities;

@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthRequestFilter implements ContainerRequestFilter {
    @Context
    HttpServletRequest webRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        final HttpSession session = webRequest.getSession();

        requestContext.setSecurityContext(new SecurityContext() {
            @Override
            public Principal getUserPrincipal() {
                return new PrincipalImpl((String)session.getAttribute("USER_NAME"));
            }

            @Override
            public boolean isUserInRole(String s) {
                return false;
            }

            @Override
            public boolean isSecure() {
                return false;
            }

            @Override
            public String getAuthenticationScheme() {
                return null;
            }
        });
    }
}

警告! 這是在澤西島2.4中引入的 Glassfish 4.0.0使用舊的Jersey 2.0,因此你必須使用這些技巧升級澤西島 (它沒有被證明效果很好)。 或者更好的方法是下載Glassfish 4.0.1的每晚版本 但目前還不完全穩定。 我希望新版本即將發布。

更新:目前(2014-02-14)Glassfish 4.0.1每晚構建使用Jersey 2.5.1並且上下文注入效果很好。

傑克對會議的回應是正確的。 它們特定於您執行的容器,盡管Servlet規范至少為您提供了JavaEE容器之間的可移植性。

至於安全性,您至少有機會通過使用JaaS(Java身份驗證和授權服務)和servlet過濾器將其與JAX-RS特定代碼分開。 過濾器可用於強制執行HTTP身份驗證,並且在成功驗證后,使用適當的主體設置JaaS主題。 您的JAX-RS資源可以檢查主題上的相應主體。 由於您控制整個堆棧,您應該能夠依賴資源中經過身份驗證的用戶(但要對此進行測試!),並且您可以根據資源代碼中的當前操作強制執行授權。

我通過讓客戶端添加Authorization標頭並在REST方法中測試它來解決這個問題,如下所示:

@GET
@PRODUCES(MediaType.APPLICATION_JSON)
public String returnClients(@Context HTTPServletRequest request(
    String auth = request.getHeader("Authorization");
    Account acc = null;
    if (auth!=null) {
       Account acc = Utils.LoginAccount(auth);
    }
    if (acc == null)
     // not logged in, handle it gracefully

這樣,無需啟動會話即可進行身份驗證。

對於Jersey安全,你應該看看球衣OAuth支持。 當您將系統的API公開給外部用戶時,OAuth非常適合。 例如像linkedin api

http://wikis.oracle.com/display/Jersey/OAuth

您可以使用@path在單個名稱空間下對服務進行分組。 例子。

@Path("/helloworld")
public class HelloWorld {

    @GET
    @Produces("text/plain")
    public String hello() {


        return "";


    }
}
Instead of @Path("/helloworld") use
@Path("admin/helloworld") to expose you class as rest and bind filter on "admin/"
in web.xml as below.

<servlet>
            <servlet-name>jersey-serlvet</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>/</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>jersey-serlvet</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>
         <filter>
            <filter-name>myfilter</filter-name>
            <filter-class>com.Filterclass</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>myfilter</filter-name>
            <url-pattern>/rest/admin/*</url-pattern>
        </filter-mapping> 

    public class Filterclass implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain)
                throws IOException, ServletException {
                  try{
                       chain.doFilter(request, response);
                    }catch(Exception e){
                   e.printStackTrace();
                       }
          }
    }

您可以在此過濾器類中驗證您的會話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM