加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java EE 7 / JAX-RS 2.0: Simple REST API Authentication &

发布时间:2020-12-14 06:20:11 所属栏目:Java 来源:网络整理
导读:REST has made a lot of conveniences when it comes to implementing web services with the already available HTTP protocol at its disposal. By just firing GET,POST and other HTTP methods through the designated URL,you’ll sure to get somethin
</tr>
<tr>
<td>auth_token</td>
<td>The token generated upon username/password authentication,which is to be used for any REST Web Service calls (except for the authentication method shown later).</td>

</tr>

REST API Implementation

For convenience and further code error reduction,let’s put the HTTP Header names into an interface as static final variables for the use in the rest of the classes.

Codes for DemoHTTPHeaderNames.java:

String SERVICE_KEY = "service_key" String AUTH_TOKEN = "auth_token"

For the implementation of the authentication process and other demo methods,the methods’ signature are defined in DemoBusinessRESTResourceProxy,along with the appropriate HTTP Methods,parameters and the business implementation is defined in DemoBusinessRESTResource.

Codes for DemoBusinessRESTResourceProxy.java:

"demo-business-resource" DemoBusinessRESTResourceProxy "login""username""password""demo-get-method""demo-post-method""logout"

Codes for DemoBusinessRESTResource.java:

= "DemoBusinessRESTResource",mappedName = "ejb/DemoBusinessRESTResource" DemoBusinessRESTResource serialVersionUID = -6663599014192066936L"password"===="auth_token"= ( ="message","Problem matching service key,username and password"=="message","Executed demoGetMethod"=="message","Executed demoPostMethod"==== ( = -1

The?login()?method is to authenticate the username,the password and also the right service key. After?login(),the authorization token will be generated and returned to the client. The client will have to use it for any other methods invocation later on. The?demoGetMethod()?and the?demoPostMethod()?are just dummy methods which returns a JSON message for demo purpose,but with a special condition that a valid authorization token must be present. The?logout()?method is to log the user out of the REST service; user is identified by the “auth_token“.

The service key and the authorization token will be made available to the REST service methods through:

@Context HttpHeaders httpHeaders

The httpHeaders,an instance of?,is an object that contains the header name and values for the use of the application further on. But in order to get the REST service to accept the HTTP Header,something needs to be done first through both the REST request interceptor and the response interceptor.

Authentication With HTTP Headers Through JAX-RS 2.0 Interceptors

Due to certain security limitation,just don’t hope that any HTTP headers could be passed using any REST client and expect the REST service to accept it. It just doesn’t work that way.

In order to make a specific header to be accepted in the REST service,we have to define the acceptance of HTTP Header very specifically in the response filter interceptor.

Codes for DemoRESTResponseFilter.java:

DemoRESTResponseFilter Logger log = Logger.getLogger( DemoRESTResponseFilter. filter( ContainerRequestContext requestCtx,ContainerResponseContext responseCtx ) "Filtering REST Response""Access-Control-Allow-Origin","*" ); responseCtx.getHeaders().add( "Access-Control-Allow-Credentials","true""Access-Control-Allow-Methods","GET,POST,DELETE,PUT""Access-Control-Allow-Headers",DemoHTTPHeaderNames.SERVICE_KEY + "," +

DemoRESTResponseFilter?is a JAX-RS 2.0 interceptor which implements?ContainerResponseFilter. Don’t forget to annotate it with both @Provide and @PreMatching. In order to allow certain specific custom HTTP headers to be accepted,the header name “Access-Control-Allow-Headers” follow by the value of custom headers with “,” as the separator must be added as part of the custom headers value. This is the way to inform the browser or REST client of the custom headers allowed. The rest of the headers are for CORS,which you can read more in one of our articles?

Next,to validate and verify the service key and authorization token,we need to extract it out from the HTTP Headers and pre-process it with the request filter interceptor.

Codes for DemoRESTRequestFilter:

DemoRESTRequestFilter Logger log = Logger.getLogger( DemoRESTRequestFilter. filter( ContainerRequestContext requestCtx ) ="Filtering request path: " + ( requestCtx.getRequest().getMethod().equals( "OPTIONS" DemoAuthenticator demoAuthenticator == ( ! ( !path.startsWith( "/demo-business-resource/login/"= ( !

To get the header value,we invoke the getHeaderString() method of the object instance of ContainerRequestContext,for example:

String serviceKey = requestCtx.getHeaderString( "service_key" );

The rest of the codes in?DemoRESTRequestFilter?is pretty straight forward on validating and verifying the service key and the authorization token.

REST Service Deployment

Don’t forget to have the web.xml for the enablement of REST service define.

Codes for web.xml:

="http://www.w3.org/2001/XMLSchema-instance"="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"="3.1"> javax.ws.rs.core.Application 1 javax.ws.rs.core.Application /rest-api ?

For this demo,I have packaged the compiled codes into a war file naming it?RESTSecurityWithHTTPHeaderDemo.war. I have chosen to deploy on Glassfish 4.0 on the domain developerscrappad.com (the domain of this blog). If you are going through everything in this tutorial,you may choose a different domain of your own. The REST API URLs will be in the format of:

http://:/RESTSecurityWithHTTPHeaderDemo/rest-api/path/method-path/

. Anyway,the summary of the URLs for the test client which I’m using are:

<table>

THE REST Client

Putting it altogether,here’s a REST client which I’ve wrote to test the REST APIs. The REST Client is just a HTML file (specifically HTML5,which supports web storage) that leverages jQuery for REST API calls. What the REST Client does is as follow:

  1. First,the REST Client will make a REST API call without service key and authorization token. The call will be rejected with HTTP Status 401 (Unauthorized)
  2. Next,it will perform a login with the specific service key (hard coded for now in the Authenticator.java) for “username2″. Once the authorisation token had been received,it will be stored in the sessionStorage for further use.
  3. Then,it will call the dummy get and post methods.
  4. After that,it will pereform a logout
  5. Once the user is logged-out,the client will then perform a call to to the dummy get and post method,but the access will be denied with HTTP Status 401 due to the expiration of the authorization token.

Codes for rest-auth-test.html:

REST Authentication Tester If this is portion is executed,something must be wrong

This is what happens when there you call the REST APIs without a service key and authorisation token. HTTP Status: Perform Login. Gotten auth-token as: After login,execute demoteGetMethod with the auth-token obtained. JSON Message: Execute demoPostMethod with the auth-token obtained. JSON message: Let's logout after all the above. No content expected.

This is what happens when someone reuses the authorisation token after a user had been logged out HTTP Status:

The Result

The?rest-auth-test.html?need not be packaged with the war file,this is to separate invoking client script from the server-side app to simulate a cross-origin request. To run the rest-auth-test.html,all you need to do is to execute it from a web browser. For me,I have done this through Firefox with the Firebug plugin,and the below is the result:

It worked pretty well. The first and the last request will be rejected as 401 (Unauthorized) HTTP Status because it was executed before authentication and after logout (invalid?auth_token).

Final Words

When it comes to dealing with custom HTTP Headers in a JAX-RS 2.0 application,just remember to have the the custom HTTP Header names to be included as part of “Access-Control-Allow-Headers” in the response filter,e.g.

Access-Control-Allow-Headers: custom_header_name1,custom_header_name2

After that,getting the HTTP Headers could be done easily in the REST Web Service methods with the help of?javax.ws.rs.core.HttpHeaders?through the REST context. Don’t forget the restriction and impact for CORS,which should be taken care in both REST Request and Response interceptors.

Thank you for reading and hope this article helps.

reference from: http://www.developerscrappad.com/1814/java/java-ee/rest-jax-rs/java-ee-7-jax-rs-2-0-simple-rest-api-authentication-authorization-with-custom-http-header/#sthash.AIH5zIyN.dpuf

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

REST has made a lot of conveniences when it comes to implementing web services with the already available HTTP protocol at its disposal. By just firing GET,POST and other HTTP methods through the designated URL,you’ll sure to get something done through a response out of a REST service. But whatever conveniences which REST has given to the developers,the subject of security and access control should always be addressed. This article will show you how to implement simple user based authentication with the use of HTTP Headers and JAX-RS 2.0 interceptors.

Authenticator

Let’s begin with an authenticator class. This DemoAuthenticator with the codes below provides the necessary methods for authenticating any users which is request access to the REST web service. Please read through the codes and the comments are there to guide the understanding.

Codes for DemoAuthenticator:

DemoAuthenticator authenticator = Map usersStorage = Map serviceKeysStorage = . Map authorizationTokensStorage = usersStorage.put( "username1","passwordForUser1""username2","passwordForUser2""username3","passwordForUser3""f80ebc87-ad5c-4b29-9366-5359768df5a1","username1""3b91cab8-926f-49b6-ba00-920bcf934c2a","username2" ( authenticator == = String login( String serviceKey,String username,String password ) = ( usernameMatch.equals( username ) &&== LoginException( "Don't Come Here Again!" == logout( String serviceKey,String authToken ) == GeneralSecurityException( "Invalid service key and authorization token match."

General Code Explanation:Generally,there are only a few important items that makes up the authenticator and that that is:?service key,?authorization token,?username?and?password. The username and password will commonly go in pairs.

Service KeyThe service key may be new to some readers; in some public REST API service,a service key and sometimes known as API key,is generated by the system and then sends to the user/client (either through email or other means) that is permitted to access the REST service. So besides login into the REST service with just mere username and password,the system will also check on the service key if the user/client is permitted to access the REST APIs. The usernames,passwords and service keys are all predefined in the codes above for now only demo purpose.

Authorization TokenUpon authentication (through the login() method),the system will then generate an authorization token for the authenticated user. This token is passed back to the user/client through HTTP response and is to be used for any REST API invocation later. The user/client will have to find a way to store and use it throughout the login session. We’ll look at that later.

Required HTTP Headers Name Definition

Moving forward,instead of having the service key and authorization token to be passed to the server-side app as HTTP parameters (Form or Query),we’ll have it pass as HTTP Headers. This is to allow the request to be first filtered before being processed by the targeted REST method. The names for the HTTP Headers are below:

HTTP Header Name
Description
    推荐文章
      热点阅读