Using spring cloud feign when http code is 401, the respose.body() is null - netflix-feign

Using the spring cloud feign call my service, when the service return 401 exception, the respose.body() is null.
When I throw the exception that is throw new BadRequestException(400, “this http code is 400”); I can get the error message that this http code is 400 by response.body().
But when I throw the exception throw new BadRequestException(401, “this http code is 401”);, the response.body() is null.
This response is feign.Response.
Why I can`t get this error message when http code is 401?
Hope your help! Thank you very much!

Switch to feign-okhttp will fix your problem.
Add in Pom:
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-okhttp</artifactId>
<version>8.18.0</version>
</dependency>
And add in your config:
feign.okhttp.enabled: true

I switched the default http client implementation to ApacheHttpClient and it works
Maven dependency:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
application:
feign.httpclient.enabled: true
Spring bean
#Bean
Client client(){
return new ApacheHttpClient();
}
As suggested in https://codingnconcepts.com/spring-boot/change-default-feign-client-implementation/

Related

How to integrat Swagger to my existing OAuth server spring boot application?

We have OAuth2 server side application created with spring boot and i am beginner with swagger and i want to integrate it with my existing Oauth server App.
First of all, now it is also available Swagger 3.0, formally knows as OpenAPI Specification, But You asking for Swagger 2.0. So, in my opinion, the best option is to use Spring Fox - https://springfox.github.io/springfox/
You only need to add the dependency:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
Then create/reuse Spring configuration(Marked by #EnableSwagger2 annotation), explained here:
http://springfox.github.io/springfox/docs/current/#quick-start-guides
And then You can customize how swagger documents your controller in the way(eg #ApiOperation annotation):
#ApiOperation(value = "Get user by id", httpMethod = "GET")
#GetMapping("/users/{id}")
public APIUser getUser(#PathVariable("id") Long id){
...
}

Writing Unit Tests for Oauth in spring boot framework

I aim to write unit test for oauth - check if user name and token was correct.
The search led me to this artical Faking OAuth SSO
For now, I am following strategy #1.
Following is the piece of code for which I need to figure out dependencies they haven't mentioned directly.
#Test
public void testGetAuthenticationInfo() throws Exception {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.apply(springSecurity())
.build();
mockMvc.perform(MockMvcRequestBuilders.get("/api/token")
.with(authentication(getOauthTestAuthentication()))
.sessionAttr("scopedTarget.oauth2ClientContext", getOauth2ClientContext()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.username").value("bwatkins"))
.andExpect(jsonPath("$.token").value("my-fun-token"));
}
I managed to arrange for webApplicationContext as below -
#Autowired
private WebApplicationContext webApplicationContext;
For springSecurity() method, I am unable to get the dependency right. Whatever I searched for led me to believe that importing org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.* will get me the method but I am unable to get the pom dependency right.
Question 1: Can anybody help me with getting the dependency right?
Question 2: for such a standard thing as OAuth, isn't there a standard spring boot test package that should just require configuration to test if oauth is working fine or not
This was an issue earlier as mentioned in the issues of spring-security github. It took some time to figure out the correct version which is 4.0.2.RELEASE
https://github.com/spring-projects/spring-security/issues/3861
Adding following in pom.xml fixed the issue.
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>

Could not resolve view with name 'forward:/oauth/confirm_access' error in Spring OAuth2

I'm getting the following error in Spring OAuth2:
javax.servlet.ServletException: Could not resolve view with name 'forward:/oauth/confirm_access' in servlet with name 'dispatcherServlet'
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1237) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
By debugging in Spring impelmentation I noticed that it is hardcoded this view name. Shouldn't it be implemented in Spring? I suppose I shall not build that view and is just a matter of configuration.
My OAuth2 authorization server and resource servers are properly configured, so I skiped that part.
Is there a configuration that handles this view?
Thanks.
P.S I am using Postman client to generate token.
I just found the problem.
The client should have autoApprove flag set on true.

Propagating AccessDeniedException in Spring Security

In my web application I am using Spring Security and Spring MVC.
I have secured a couple of methods with #Secured annotation and configured Spring Security in such a way that when one of those methods is accessed without the proper role, the user is taken to the login page. However, I do not want that behaviour when the offending request comes from Ajax, so I implemented the custom #ExceptionHandler annotated method to determine the request's context.
This is my exception handler:
#ExceptionHandler(AccessDeniedException.class)
public void handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (isAjax(request)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
throw ex;
}
}
This way I can both handle the exception myself (for example, log an attempt of accessing the #Secured method) and then let Spring do its part and redirect the user to the login page by rethrowing the AccessDeniedException. Also, when the request comes from Ajax I set the response status to SC_UNAUTHORIZED and handle the error on the client side.
Now, this seems to be working fine, but I am getting the following ERROR each time I rethrow the exception from the handleAccessDeniedException method:
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke #ExceptionHandler method: public void app.controller.BaseController.handleAccessDeniedException(org.springframework.security.access.AccessDeniedException,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception
org.springframework.security.access.AccessDeniedException:
at app.controller.BaseController.handleAccessDeniedException(BaseController.java:23)
at app.controller.BaseController$$FastClassByCGLIB$$8f052058.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
(...)
I have not added any exception handling specifics to spring xml configuration files.
I do not see any issues with the app itself, but the error is there and since I am quite new to Spring MVC and Spring Security, I am guessing that I am not doing this properly. Any suggestions? Thanks!
Your exception handler isn't supposed to throw another exception. It's supposed to deal with it and send a response. It's a good idea to check the code if you get an error from a class to see how it behaves.
For the non-ajax case, you'd be better to redirect the response to the login page, if that's what you want. Alternatively, you can customize the AuthenticationEntryPoint used by Spring Security instead and omit AccessDeniedExceptions from MVC handling. The behaviour would essentially be the same as the defaul LoginUrlAuthenticationEntryPoint but you would extend it to return a 403 when an ajax request is detected.

HTTP requests in a PlayN project

I want to use RequestBuilder to make HTTP requests in my PlayN project as described here:
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideHttpRequests
I added the tag in my module xml file:
but I still have the following compilation error:
The import com.google cannot be resolved
Is there something else I should do to make my project compile?
Here is the code:
import com.google.gwt.http.client.*;
...
String url = "http://www.myserver.com/getData?type=3";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP violation, etc.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
} else {
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
If you're using Maven for your build (which I suspect you may be), make absolutely sure that the following dependency is in your html/pom.xml
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
You might need to change the version if you're using a version of GWT other than 2.4.0
Edit: Now that I know you are running a Java application (based on the comments below) and not a GWT application, you're likely going to need to make HTTP requests with something other than GWT's HTTP client. You'll want to remove the aforementioned dependency and take a look at the answers to this question for some insight into how to do that...
If you're needing to make HTTP requests in both the GWT and Java PlayN targets, you're likely going to need to abstract the HTTP client interface needed in the core module and provide the appropriate concrete implementations in the java and GWT modules. I describe using Gin and Guice to inject java and GWT specific instances of AsyncService<> objects in this answer here, and a similar approach can be used in injecting the appropriate HTTP client instance required on a per platform basis if necessary...

Resources