<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # RESTEasy 基本認證和授權教程 > 原文: [https://howtodoinjava.com/resteasy/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/](https://howtodoinjava.com/resteasy/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/) 安全性是任何企業應用不可或缺的一部分。 安全涉及兩個階段,即認證和授權。 **認證可驗證您的身份。 授權會驗證您有權執行的操作。** 在本文中,我們將學習為 REST API 構建基于角色的基本認證/授權安全性。 ```java Sections in this post: Background information Important classes/annotations used Building the security interceptor Testing authorization and authentication on REST APIs ``` ## 背景信息 在本文中,我將嘗試**解決以下安全問題**: * 從 http 請求獲取用戶名和密碼 * 獲取適用的方法安全性詳細信息 * 驗證用戶是否有權訪問 API * 如果訪問無效,則返回有效的錯誤代碼 另外,請注意,我正在**為您實現以下部分**: * 訪問數據庫以獲取密碼,以驗證請求中提供的密碼 * 從數據庫中為有效用戶獲取允許的角色 我正在重用為 [**ETag 使用演示**](//howtodoinjava.com/2013/06/05/jax-rs-resteasy-cache-control-with-etag-example/ "JAX-RS RESTEasy Cache control with ETag example")編寫的代碼。 該項目有 2 個主要類: **`User.java`**:代表系統中用戶資源的模型類 ```java @XmlAccessorType(XmlAccessType.NONE) @XmlRootElement(name = "user") public class User implements Serializable { @XmlAttribute(name = "id") private int id; @XmlAttribute(name="uri") private String uri; @XmlElement(name = "firstName") private String firstName; @XmlElement(name = "lastName") private String lastName; @XmlElement(name="last-modified") private Date lastModified; //Getters and setters } ``` **`UserService.java`**:此類具有 GET 和 PUT API,用于獲取/修改用戶資源。 ```java @Path("/user-service") public class UserService { @GET @Path("/users/{id}") public Response getUserById(@PathParam("id") int id, @Context Request req) { Response.ResponseBuilder rb = Response.ok(UserDatabase.getUserById(id)); return rb.build(); } @PUT @Path("/users/{id}") public Response updateUserById(@PathParam("id") int id) { //Update the User resource UserDatabase.updateUser(id); return Response.status(200).build(); } } ``` 在本教程中,我將使用上述 2 個 API 并確保它們的安全。 ## 使用的重要類/注解 JAX-RS 提供必要的注解,以在基于 RESTEasy 的應用中實現安全性。 重要的注解是: * [`javax.annotation.security.PermitAll`](https://docs.oracle.com/javaee/6/api/javax/annotation/security/PermitAll.html "PermitAll"):此注解應用于 API 時,用于聲明任何用戶都可以自由訪問該 API。 此 API 沒有訪問限制。 * [`javax.annotation.security.DenyAll`](https://docs.oracle.com/javaee/6/api/javax/annotation/security/DenyAll.html "DenyAll"):此注解用于聲明無論分配給任何用戶的角色,都不允許任何人訪問此 API。 * [`javax.annotation.security.RolesAllowed`](https://docs.oracle.com/javaee/6/api/javax/annotation/security/RolesAllowed.html "RolesAllowed"):此注解有助于標識訪問該 API 的任何用戶都需要哪些角色。 如果通過用戶/名稱和密碼驗證了用戶,但沒有此注解指定的角色,則將不允許該用戶訪問。 * [`javax.ws.rs.core.HttpHeaders`](https://docs.oracle.com/javaee/6/api/javax/ws/rs/core/HttpHeaders.html "HttpHeaders"):一個接口,提供對與 http 請求一起附加的 HTTP 標頭信息的訪問。 * [`org.jboss.resteasy.util.Base64`](http://docs.jboss.org/resteasy/docs/2.3.0.GA/javadocs/org/jboss/resteasy/util/Base64.html "Base64"):此類有助于在 Base64 表示法之間進行編碼和解碼。 除上述類外,[`org.jboss.resteasy.spi.interception.PreProcessInterceptor`](http://docs.jboss.org/resteasy/docs/1.2.GA/javadocs/org/jboss/resteasy/spi/interception/PreProcessInterceptor.html "PreProcessInterceptor")將用于創建安全攔截器。 [`javax.ws.rs.ext.Provider`](http://docs.jboss.org/resteasy/docs/1.0.2.GA/javadocs/javax/ws/rs/ext/class-use/Provider.html "Provider")注解將用于在 resteasy 上下文中注冊攔截器。 ## 構建安全攔截器 在構建攔截器之前,請確保 API 的安全。 我在 GET/PUT API 中添加了`@PermitAll`和`@RolesAllowed`注解。 GET API 向所有人開放,即沒有訪問限制。 PUT API 需要具有`ADMIN`功能的有效用戶。 ```java @Path("/user-service") public class UserService { @PermitAll @GET @Path("/users/{id}") public Response getUserById(@PathParam("id") int id, @Context Request req) { Response.ResponseBuilder rb = Response.ok(UserDatabase.getUserById(id)); return rb.build(); } @RolesAllowed("ADMIN") @PUT @Path("/users/{id}") public Response updateUserById(@PathParam("id") int id) { //Update the User resource UserDatabase.updateUser(id); return Response.status(200).build(); } } ``` 通過實現`org.jboss.resteasy.spi.interception`.`PreProcessInterceptor`接口來構建安全攔截器。 該接口有一個實現類的類需要實現的方法。 ```java public ServerResponse preProcess(HttpRequest request, ResourceMethod methodInvoked) throws Failure, WebApplicationException; ``` `methodInvoked`參數提供對方法的訪問,該方法將由于調用 REST API 而被調用。 請求參數提供對客戶端傳遞的請求標頭和參數的訪問。 攔截器類的定義如下: ```java @Provider @ServerInterceptor public class SecurityInterceptor implements PreProcessInterceptor { //more code } ``` `@Provider`進行 resteasy 上下文掃描,以將該類添加為上下文類。 `@ServerInterceptor`注解將此類添加到可用的攔截器列表中。 現在,第一步是檢查 API 是否對所有人都打開或對所有人都關閉。 這可以通過檢查`@PermitAll`和`@DenyAll`注解來完成。 ```java Method method = methodInvoked.getMethod(); //Access allowed for all if(method.isAnnotationPresent(PermitAll.class)) { return null; //Return null to continue request processing } //Access denied for all if(method.isAnnotationPresent(DenyAll.class)) { return ACCESS_FORBIDDEN; //Return access denied to user } ``` 下一步是從請求中獲取授權標頭。 從授權標頭中,我們將檢索用戶發送的用戶名和密碼。 ```java //Get request headers final HttpHeaders headers = request.getHttpHeaders(); //Fetch authorization header final List<String> authorization = headers.getRequestHeader(AUTHORIZATION_PROPERTY); //If no authorization information present; block access if(authorization == null || authorization.isEmpty()) { return ACCESS_DENIED; } //Get encoded username and password final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", ""); //Decode username and password String usernameAndPassword; try { usernameAndPassword = new String(Base64.decode(encodedUserPassword)); } catch (IOException e) { return SERVER_ERROR; } //Split username and password tokens final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":"); final String username = tokenizer.nextToken(); final String password = tokenizer.nextToken(); ``` 現在,我們將從`@RolesAllowed`注解中獲取訪問 API 所需的角色。 ```java RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class); Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value())); ``` `RolesSet`包含所有可以允許 API 訪問的角色。 現在,在最后一步中,我們必須做兩件事。 首先,從任何數據庫服務驗證用戶名和密碼,如果用戶有效,則獲取分配給他的角色。 該角色將用于檢查用戶的認證成功。 ```java if(rolesSet.contains(userRole)) { isAllowed = true; } ``` `SecurityInterceptor.java`的完整源代碼如下所示: ```java /** * This interceptor verify the access permissions for a user * based on username and passowrd provided in request * */ @Provider @ServerInterceptor public class SecurityInterceptor implements PreProcessInterceptor { private static final String AUTHORIZATION_PROPERTY = "Authorization"; private static final String AUTHENTICATION_SCHEME = "Basic"; private static final ServerResponse ACCESS_DENIED = new ServerResponse("Access denied for this resource", 401, new Headers<Object>());; private static final ServerResponse ACCESS_FORBIDDEN = new ServerResponse("Nobody can access this resource", 403, new Headers<Object>());; private static final ServerResponse SERVER_ERROR = new ServerResponse("INTERNAL SERVER ERROR", 500, new Headers<Object>());; @Override public ServerResponse preProcess(HttpRequest request, ResourceMethod methodInvoked) throws Failure, WebApplicationException { Method method = methodInvoked.getMethod(); //Access allowed for all if(method.isAnnotationPresent(PermitAll.class)) { return null; } //Access denied for all if(method.isAnnotationPresent(DenyAll.class)) { return ACCESS_FORBIDDEN; } //Get request headers final HttpHeaders headers = request.getHttpHeaders(); //Fetch authorization header final List<String> authorization = headers.getRequestHeader(AUTHORIZATION_PROPERTY); //If no authorization information present; block access if(authorization == null || authorization.isEmpty()) { return ACCESS_DENIED; } //Get encoded username and password final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", ""); //Decode username and password String usernameAndPassword; try { usernameAndPassword = new String(Base64.decode(encodedUserPassword)); } catch (IOException e) { return SERVER_ERROR; } //Split username and password tokens final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":"); final String username = tokenizer.nextToken(); final String password = tokenizer.nextToken(); //Verifying Username and password System.out.println(username); System.out.println(password); //Verify user access if(method.isAnnotationPresent(RolesAllowed.class)) { RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class); Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value())); //Is user valid? if( ! isUserAllowed(username, password, rolesSet)) { return ACCESS_DENIED; } } //Return null to continue request processing return null; } private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet) { boolean isAllowed = false; //Step 1\. Fetch password from database and match with password in argument //If both match then get the defined role for user from database and continue; else return isAllowed [false] //Access the database and do this part yourself //String userRole = userMgr.getUserRole(username); String userRole = "ADMIN"; //Step 2\. Verify user role if(rolesSet.contains(userRole)) { isAllowed = true; } return isAllowed; } } ``` ## 在 REST API 上測試授權和認證 要測試安全代碼,請將 Web 應用部署在任何應用服務器(例如 Tomcat)中。 現在,發送以下請求: **HTTP GET `http://localhost:8080/RESTEasyEtagDemo/user-service/users/1`,沒有用戶名和密碼** 用戶能夠成功訪問 API。 ![resteasy authorization test get api](https://img.kancloud.cn/29/94/29945236d0cc1b93e13bf59cd34c98d4_945x382.png) **HTTP PUT `http://localhost:8080/RESTEasyEtagDemo/user-service/users/1`,沒有用戶名和密碼** 用戶無法訪問 API。 ![resteasy authorization test get api](https://img.kancloud.cn/ec/28/ec28901443f17ceb03557f5d69d37e6a_949x376.png) **添加基本授權憑證** ![Add basic authorization credentials](https://img.kancloud.cn/aa/f1/aaf1e0084104d852f7f07556a783f425_591x297.png) **HTTP PUT `http://localhost:8080/RESTEasyEtagDemo/user-service/users/1`,其中添加了用戶名和密碼** 用戶能夠訪問受保護的 API ![resteasy authorization test put api 2](https://img.kancloud.cn/9f/7a/9f7af3333fb0d52d55a0c60f43816007_952x458.png) 這就是本教程中的全部內容。 如果您有任何疑問或建議,請給我評論。 [**下載源代碼**](https://docs.google.com/file/d/0B7yo2HclmjI4U1BkQzZTV3VjVVk/edit?usp=sharing "JAX-RS RESTEasy basic authentication tutorial sourcecode") **祝您學習愉快!**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看