I have a spring boot application and I have to connect to some outside service using SSE. WebClient establishes the connection and then I'm using Flux for reading responses. Everything works ok, but the problem is that the connection stays open, because the process is not designed to reach the finish point every time in that 3rd party service. I would like to close the connection manually as a client since I know when this connection should finish. How can I do that?
Establishing connection:
private Flux<ServerSentEvent<String>> connect(String accessToken) {
TcpClient timeoutClient = createTimeoutClient();
ReactorClientHttpConnector reactorClientHttpConnector = new ReactorClientHttpConnector(HttpClient.from(timeoutClient));
String url = npzServerBaseUrl+uniqueCodePath;
WebClient client = WebClient
.builder()
.clientConnector(reactorClientHttpConnector)
.defaultHeader(HttpHeaders.AUTHORIZATION, Naming.TOKEN_PREFIX + accessToken)
.baseUrl(url)
.build();
ParameterizedTypeReference<ServerSentEvent<String>> type
= new ParameterizedTypeReference<ServerSentEvent<String>>() {};
return client.get()
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> {
String msg = "Error from server: "+clientResponse.statusCode().toString();
//invalidate access token
if (clientResponse.statusCode().value()==401) {
//remove invalid token and connect again
loginContext.invalidToken(accessToken);
return Mono.error(new InvalidNpzToken(msg));
}
return Mono.error(new IllegalStateException(msg));
}
)
.onStatus(HttpStatus::is5xxServerError, clientResponse ->
Mono.error(new IllegalStateException("Error from server: "+clientResponse.statusCode().toString()))
)
.bodyToFlux(type);
}
private TcpClient createTimeoutClient() {
return TcpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, SECONDS*1000)
.option(EpollChannelOption.TCP_USER_TIMEOUT, SECONDS*1000)
.doOnConnected(
c -> c.addHandlerLast(new ReadTimeoutHandler(SECONDS))
.addHandlerLast(new WriteTimeoutHandler(SECONDS)));
}
Handling content:
Flux<ServerSentEvent<String>> eventStream = connect(accessToken);
eventStream.subscribe(
content -> {
log.info("Time: {} - event: name[{}], id [{}], content[{}] ",
LocalTime.now(), content.event(), content.id(), content.data());
if ("uuid".equals(content.event().trim())) {
listener.receivedUniqueCode(content.data().trim());
} else if ("code".equals(content.event().trim())) {
listener.receivedCode(content.data().trim());
}
},
(Throwable error) -> {
if (error instanceof InvalidToken) {
log.error("Error receiving SSE", error);
//let's retry connection as token has expired
getCode(request, listener);
}
},
() -> log.info("Connection closed!"));
What I expect is that I can call connection.close() or something like that and connection will be closed.
Thanks
Some more information if needed.
Imports:
import io.netty.channel.ChannelOption;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
Spring boot:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
eventStream.subscribe() returns a reactor.core.Disposable
You can call dispose() on it to cancel the subscription and the underlying resources.
Related
I want to customize the 401/403 status code when access token is invalid in headers. I have create an exception mapper given below :
import io.quarkus.security.AuthenticationFailedException;
import org.jose4j.json.internal.json_simple.JSONObject;
import javax.annotation.Priority;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
#Provider//register as JAXRS provider
#Priority(1)
public class UnAuthorizedExceptionMapper implements ExceptionMapper<AuthenticationFailedException> {
#Override
public Response toResponse(AuthenticationFailedException exception) {
System.out.println("I m here:"+exception);
JSONObject ob=new JSONObject();
ob.put("errorCode",401);
ob.put("msg","Invalid access token");
return Response.status(Response.Status.UNAUTHORIZED)
.entity(ob.toJSONString())
.build();
}
}
But when I execute my code then above exception mapper is not executed instead following log is appearing in the console :
io.qua.oid.run.OidcProvider: (vert.x-eventloop-thread-1) Token verification has failed: The JWT is no longer valid - claim value.
How can I customize 401/403 status code msg in quarkus oidc.
I have seen this issue being addressed in many other posts but none of them has solved my problem. I have a front-end Vue.js application and a spring boot Java application.
I am using the vue-google-oauth to prompt the Google sign in from my front end application to get the auth code, then I wanted to use my backend server to get user details and handle logic there.
On Google Cloud Platform I defined an Authorized redirect URI:
and I am using this very same uri when I am sending my auth code in the front end
import api from "#/assets/js/api";
import AdminNavigation from "./AdminNavigation";
import { mapGetters } from "vuex";
import Axios from "axios";
export default {
name: "Dashboard",
computed: {
...mapGetters(["IsSignedIn"]),
},
data() {
return {
title: "Christopher s' portfolio admin",
appDescription:
"Here you can add contents for the front end portfolio website.",
isInit: false,
};
},
components: {
AdminNavigation,
},
methods: {
signIn: async function () {
try {
const authCode = await this.$gAuth.getAuthCode();
Axios.post("http://localhost:8080/authenticate", {
code: authCode,
redirect_uri: "http://localhost:3000/admin/dashboard",
});
} catch (err) {
console.log(err);
}
},
},
mounted() {
let that = this;
let checkGauthLoad = setInterval(function () {
that.isInit = that.$gAuth.isInit;
if (!this.IsSignedIn) {
that.signIn();
}
if (that.isInit) clearInterval(checkGauthLoad);
}, 1000);
},
};
My backend server receives the auth code and the redirect_uri which is identical to what was defined on Google Cloud Platform.
package com.salay.christophersalayportfolio.controllers;
import com.google.api.client.auth.oauth2.TokenResponseException;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.salay.christophersalayportfolio.general.ConstantVariables;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;
#Controller
public class AdminController {
#CrossOrigin(origins = "http://localhost:3000")
#RequestMapping(value = "/authenticate", method = RequestMethod.POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
#ResponseBody
public String authentication(HttpEntity<String> data) throws IOException, ParseException {
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(data.getBody());
String authCode = json.get("code").toString();
String redirect_uri = json.get("redirect_uri").toString();
try {
GoogleTokenResponse response =
new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(),
ConstantVariables.GOOGLE_CLIENT_ID,
ConstantVariables.GOOGLE_CLIENT_SECRET,
authCode, redirect_uri).execute();
System.out.println("Access token: " + response.getAccessToken());
} catch (TokenResponseException e) {
if (e.getDetails() != null) {
System.err.println("Error: " + e.getDetails().getError());
if (e.getDetails().getErrorDescription() != null) {
System.err.println(e.getDetails().getErrorDescription());
}
if (e.getDetails().getErrorUri() != null) {
System.err.println(e.getDetails().getErrorUri());
}
} else {
System.err.println(e.getMessage());
}
}
return "";
}
}
But I get the following error:
400 Bad Request redirect_uri_mismatch
I kept looking at a lot of stack overflow questions and no solution worked for me so far... any ideas?
Sounds like you are not sending the OAuth details you think you are. Have you captured HTTPS messages to the Authorization Server from your Spring Boot back end - and can you post details here?
If it helps, this blog post of mine includes some notes on configuring an HTTP proxy in Java.
I was going through these docs to create an elastic search index from Elastic's high level JAVA REST client. It seems to skip over steps for authenticating with my elastic cloud account.
Can someone please point me toward the relevant documentation?
I launched my elastic search instance and copied the endpoint URL into my client code.
I initially had connection errors and now there are none. Only authentication errors. So, I'm pretty sure I'm connecting with the correct endpoint URL and need to authenticate somehow - perhaps with a header.
Now, I am seeing this error:
Elasticsearch exception [type=security_exception, reason=action
[indices:data/write/index] requires authentication]
I can view the endpoint of my Elastic Search deployment with no problems from Postman with this command:
GET https://:#d97215aee2.us-east-1.aws.found.io:9243
I can also create an index using this command from Postman...
PUT https://elastic:4YQIMXfoSZ9mXPgY1fj7T5BU#d97218f74f6d48489b355dd7d665aee2.us-east-1.aws.found.io:9243/. Yet, I cannot do the same from the Java code.
Here is the state of my Java code. It is pretty much the code from these tutorial pages.
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-getting-started-initialization.html
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.4/java-rest-high-document-index.html
import java.io.IOException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.apache.http.HttpHost;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
#Path("/elasticsearch")
public class ElasticSearchService {
#POST
public void createElasticIndex() throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("d9<deleted a bunch of characters for privacy>7d665aee2.us-east-1.aws.found.io", 9243, "https")));
IndexRequest request = new IndexRequest(
"posts",
"doc",
"1");
String jsonString = "{" +
"\"user\":\"kimchy\"," +
"\"postDate\":\"2013-01-30\"," +
"\"message\":\"trying out Elasticsearch\"" +
"}";
request.source(jsonString, XContentType.JSON);
client.close();
}
}
I have also tried updating the URL address with our username and password as suggested by this post: ElasticSearch authentication error with ElasticCloud?
Essentially, I updated my URL like this...
RestClient.builder(
new HttpHost(
"<my user name>:<my password>#d97218<hidden characters>d665aee2.us-east-1.aws.found.io",
9243, "https")));
This did not work for me. I am guessing this person wasn't using the new Elastic
High Level REST client.
I received this error:
org.glassfish.jersey.server.internal.process.MappableException:
java.io.IOException: :#d97265aee2.us-east-1.aws.found.io: invalid IPv6 address
Found the answer here: enter link description here
Updated code that works:
import java.io.IOException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
#Path("/elasticsearch")
public class ElasticSearchService {
private static final String ELASTIC_SEARCH_USER_NAME = <my elastic search username>;
private static final String ELASTIC_SEARCH_PASSWORD = <my elastic search password>;
private static final String ELASTIC_SEARCH_ENDPOINT_URL = <my elastic search endpoint url>
private static final Integer ELASTIC_SEARCH_PORT = 9243;
#POST
public void createElasticIndex() throws IOException {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(ELASTIC_SEARCH_USER_NAME, ELASTIC_SEARCH_PASSWORD));
RestClientBuilder builder = RestClient
.builder(new HttpHost(
ELASTIC_SEARCH_ENDPOINT_URL,
ELASTIC_SEARCH_PORT, "https"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
#Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
RestHighLevelClient client = new RestHighLevelClient(builder);
IndexRequest request = new IndexRequest(
"contacts",
"doc",
"1");
String jsonString = "{" +
"\"user\":\"frank\"," +
"\"postDate\":\"2020-03-02\"," +
"\"message\":\"created this document from Java\"" +
"}";
request.source(jsonString, XContentType.JSON);
try {
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
client.close();
}
}
This code creates an index called contacts and adds a document to that index.
You can use both synchronous and asynchronous API of elastic search to create index. But it depends on requirement.
Find the below link of elastic search documentation which explain both synchronous and asynchronous API use.
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/master/java-rest-high-create-index.html
Sample code:-
Synchronous API :-
CreateIndexRequest request = new CreateIndexRequest("twitter");
request.settings(Settings.builder()
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 2)
);
CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
Asynchronous API:-
client.indices().createAsync(request, RequestOptions.DEFAULT, listener);
Asynchronous API adds advantages of thread and makes API to work better way. Concern in asynchronous API is to receive response. Below is the snippet how can you receive response.
PlainActionFuture<CreateIndexResponse > future = new PlainActionFuture<>();
client.indices().createAsync(request, RequestOptions.DEFAULT, future);
CreateIndexResponse response = future.actionGet();
If you know how to insert documents through API then this way will much more easy for you to do anything similar API (DELETE,POST,PUT...)
First, you will need RestHighLevelClient and all you have to do
String index = "/indexName/_doc";
Request request = new Request("POST", index);
request.setJsonEntity(
"{ \"message\": \" example add insert\" }"
);
client.getLowLevelClient().performRequest(request);
This will execute like how API does.
My gateway will redirect traffic to many different services (under different domain names). how can i test the gateway's configuration? with only one service i can just setup the mock server (like httpbin) and test the response. with multiple services i'd prefer to avoid starting the whole docker network or changing the locak dns aliases. does spring offer any lightweight way of testing the gateway?
Here is how to achieve what you want with the API Simulator:
package my.package;
import static com.apisimulator.embedded.SuchThat.isEqualTo;
import static com.apisimulator.embedded.SuchThat.startsWith;
import static com.apisimulator.embedded.http.HttpApiSimulation.httpApiSimulation;
import static com.apisimulator.embedded.http.HttpApiSimulation.httpRequest;
import static com.apisimulator.embedded.http.HttpApiSimulation.httpResponse;
import static com.apisimulator.embedded.http.HttpApiSimulation.simlet;
import static com.apisimulator.http.Http1Header.CONTENT_TYPE;
import static com.apisimulator.http.HttpMethod.CONNECT;
import static com.apisimulator.http.HttpMethod.GET;
import static com.apisimulator.http.HttpStatus.OK;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import java.time.Duration;
import java.util.Map;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.util.SocketUtils;
import com.apisimulator.embedded.http.JUnitHttpApiSimulation;
#RunWith(SpringRunner.class)
#SpringBootTest(
webEnvironment = RANDOM_PORT,
properties = {
"management.server.port=${test.port}", "logging.level.root=info",
// Configure the Gateway to use HTTP proxy - the API Simulator
// instance running at localhost:6090
"spring.cloud.gateway.httpclient.proxy.host=localhost",
"spring.cloud.gateway.httpclient.proxy.port=6090"
//"logging.level.reactor.netty.http.server=debug",
//"spring.cloud.gateway.httpserver.wiretap=true"
}
)
#Import(ServiceGatewayApplication.class)
public class ServiceGatewayApplicationTest
{
// Configure an API simulation. This starts up an instance
// of API Simulator on localhost, default port 6090
#ClassRule
public static final JUnitHttpApiSimulation clApiSimulation = JUnitHttpApiSimulation
.as(httpApiSimulation("svc-gateway-backends"));
protected static int managementPort;
#LocalServerPort
protected int port = 0;
protected String baseUri;
protected WebTestClient webClient;
#BeforeClass
public static void beforeClass()
{
managementPort = SocketUtils.findAvailableTcpPort();
System.setProperty("test.port", String.valueOf(managementPort));
// Configure simlets for the API simulation
// #formatter:off
clApiSimulation.add(simlet("http-proxy")
.when(httpRequest(CONNECT))
.then(httpResponse(OK))
);
clApiSimulation.add(simlet("test-domain-1")
.when(httpRequest()
.whereMethod(GET)
.whereUriPath(isEqualTo("/static"))
// The `host` header is used to determine the actual destination
.whereHeader("host", startsWith("domain-1.com"))
)
.then(httpResponse()
.withStatus(OK)
.withHeader(CONTENT_TYPE, "application/text")
.withBody("{ \"domain\": \"1\" }")
)
);
clApiSimulation.add(simlet("test-domain-2")
.when(httpRequest()
.whereMethod(GET)
.whereUriPath(isEqualTo("/v1/api/foo"))
.whereHeader("host", startsWith("domain-2.com"))
)
.then(httpResponse()
.withStatus(OK)
.withHeader(CONTENT_TYPE, "application/json; charset=UTF-8")
.withBody(
"{\n" +
" \"domain\": \"2\"\n" +
"}"
)
)
);
// #formatter:on
}
#AfterClass
public static void afterClass()
{
System.clearProperty("test.port");
}
#Before
public void setup()
{
// #formatter:off
baseUri = "http://localhost:" + port;
webClient = WebTestClient.bindToServer()
.baseUrl(baseUri)
.responseTimeout(Duration.ofSeconds(2))
.build();
// #formatter:on
}
#Test
public void test_domain1()
{
// #formatter:off
webClient.get()
.uri("/static")
.exchange()
.expectStatus().isOk()
.expectBody(String.class).consumeWith(result ->
assertThat(result.getResponseBody()).isEqualTo("{ \"domain\": \"1\" }")
);
// #formatter:on
}
#Test
public void test_domain2()
{
// #formatter:off
webClient.get()
.uri("/v1/api/foo")
.exchange()
.expectStatus().isOk()
.expectHeader()
.contentType("application/json; charset=UTF-8")
.expectBody(Map.class).consumeWith(result ->
assertThat(result.getResponseBody()).containsEntry("domain", "2")
);
// #formatter:on
}
}
Most of the code is based on this GatewaySampleApplicationTests class from the Spring Cloud Gateway project.
The above assumes the Gateway has routes similar to these (snippets only):
...
uri: "http://domain-1.com"
predicates:
- Path=/static
...
uri: "http://domain-2.com"
predicates:
- Path=/v1/api/foo
...
#apsisim provided a great idea to use web proxy. but the tool he suggests is not in any maven repo and has commercial license. what worked for me:
run the gateway so it will use a proxy (u can be more fancy and find a free port):
private const val proxyPort = 1080
#SpringBootTest(
properties = [
//"logging.level.reactor.netty.http.server=debug",
//"spring.cloud.gateway.httpserver.wiretap=true",
//"spring.cloud.gateway.httpclient.wiretap=true",
"spring.cloud.gateway.httpclient.proxy.host=localhost",
"spring.cloud.gateway.httpclient.proxy.port=$proxyPort"
]
)
then use the mockwebserver as a proxy
testImplementation("com.squareup.okhttp3:mockwebserver:4.2.1")
testImplementation("com.squareup.okhttp3:okhttp:4.2.1")
and then all your requests will go to your proxy. just remember that http protocol specifies that first request to new server requires tunneling via the proxy so when u do first request to the gateway, the gateway will send 2 requests to the proxy:
testClient.get()
.uri(path)
.header("host", gatewayDns)
.exchange()
nextRequestFromGateway {
method `should equal` "CONNECT"
headers[HOST] `should equal` "$realUrlBehindGateway:80"
}
nextRequestFromGateway {
path `should equal` "/api/v1/whatever"
headers[HOST] `should equal` realUrlBehindGateway
}
...
fun nextRequestFromGateway(block : RecordedRequest.() -> Unit) {
mockWebServer.takeRequest().apply (block)
}
Hi I have implemanted one basic example of RESTful web services ,I am trying to implement Oauth client and Server (Provider) in my src folder of eclipse.
This is my OauthClient.java
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;
import com.sun.jersey.api.client.*;
import com.sun.jersey.oauth.client.OAuthClientFilter;
import com.sun.jersey.oauth.signature.OAuthParameters;
import com.sun.jersey.oauth.signature.OAuthSecrets;
import javax.ws.rs.core.*;
#Path("/OauthClient")
#RolesAllowed({"admin"})
public class OauthClient
{
#GET
#Path("/oauth_client")
#Produces(MediaType.TEXT_PLAIN)
public String oauthClient()
{
// establish the parameters that will be used to sign the request
OAuthParameters params = new OAuthParameters().consumerKey("hoge").signatureMethod("HMAC-SHA1").timestamp().nonce().version("1.1").token("sho1get");
// establish the secrets that will be used to sign the request
OAuthSecrets secrets = new OAuthSecrets().consumerSecret("testtest").tokenSecret("testtest");
Client client = Client.create();
// OAuth test server resource
WebResource resource = client.resource("http://localhost:8080/RestfulWS/rest/OauthServer/oauth_provider");
// if parameters and secrets remain static, filter can be added to each web resource
OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(), params, secrets);
// filter added at the web resource level
resource.addFilter(filter);
System.out.println("==== Client =====");
// make the request (signing it in the process)
return resource.get(String.class);
}
}
and OauthServer.java is
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
//import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.oauth.server.OAuthServerRequest;
import com.sun.jersey.oauth.signature.OAuthParameters;
import com.sun.jersey.oauth.signature.OAuthSecrets;
import com.sun.jersey.oauth.signature.OAuthSignature;
import com.sun.jersey.oauth.signature.OAuthSignatureException;
#Path("/OauthServer")
#RolesAllowed({"admin"})
public class OauthServer {
#GET
#Path("/oauth_provider")
#Produces(MediaType.TEXT_PLAIN)
public String oauthProvider(#Context HttpContext context)
{
// wrap an existing request with server request
OAuthServerRequest request = new OAuthServerRequest(context.getRequest());
// baseline OAuth parameters for access to resource
OAuthParameters params = new OAuthParameters().readRequest(request);
// OAuth secrets to access resource
OAuthSecrets secrets = new OAuthSecrets().consumerSecret("hoge").tokenSecret("testtest");
// String timestamp = params.getTimestamp();
try {
/* The error occurs here. */
if (OAuthSignature.verify(request, params, secrets)) {
return "OK";
}
} catch (OAuthSignatureException e) {
// log.warning(e.getMessage());
// } catch (UniformInterfaceException e) {
//// log.warning(e.getMessage());
// } catch (Exception e) {
// log.warning(e.getMessage());
}
return "ERROR";
}
}
how to run this to achive Oauth authentication ,do we have to write some JSP? please suggest something.