ASP.NET Web API Authentication and Validation - asp.net-mvc-3

I use ASP.NET Web API and use Authentication by reference to http://stevescodingblog.co.uk/basic-authentication-with-asp-net-webapi/
It works well.If the request which has not Authorization header, response HttpStatusCode is "Unauthorized".
But when some json data send from clientside which has some incorrect column, response HttpStatusCode is "Internal Server Error" though the request has not Authorization header.
[BasicAuthentication]
public HttpResponseMessage Create(Customer customer)
{
//
}
public class Customer{
public int id{set;get;}
public string name{set;get;}
}
For example, send POST method to /Create, Content-Type is application/json, and Request Body { "id": "abc", "name": "someone" }(id is wrong:not int but string) and don't have Authorization header. Response HttpStatusCode is "Internal Server Error" not "Unauthorized".
Maybe creating customer instance is earlier than Authorization. Do you know to change Authorization first?

If you've created your BasicAuthenthication attribute as an ActionFilterAttribute, you can try changing it to a AuthorizationFilterAttribute. OnActionExecuting will then change to OnAuthorization. I think most of the rest of it should be fairly similar.

Related

IllegalArgumentException: The HTTP header line does not conform to RFC 7230 when POST-accessing Spring Controller

I want to implement a user registration functionality with Spring. When I try to POST the data to the spring controller, the exception above is thrown. Surprisingly, GET Requests work on the controller.
#RestController
#RequestMapping(RestApi.ANONYMOUS + "register")
public class RegisterController {
#PostMapping(value="/new", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public UserRegistrationResultDto registerUser(#RequestBody UserRegisterDto dto) {
UserRegistrationResultDto result = registerService.registerUser(dto.getMail(),
dto.getPassword(), dto.getRepeatedPassword());
return result;
}
#GetMapping("/test")
public String test() {
return "get success";
}
}
The request that fails with error code 400 is the following:
POST http://localhost:8080/api/anonymous/register/new
Content-Type:application/x-www-form-urlencoded
{
mail=data&password=data&passwordRepeated=data
}
It throws the following exception:
java.lang.IllegalArgumentException: The HTTP header line [{: ] does not conform to RFC 7230 and has been ignored.
This get request however works:
GET http://localhost:8080/api/anonymous/register/test
I am using Tomcat 9 as a server.
Not sure how the POST request is submitted...but a space after : is required for HTTP header fields:
Content-Type: application/x-www-form-urlencoded

Getting 403 forbidden error using #PostMapping via rest api in spring boot project

I am getting 403 forbidden error on postman while accessing #PostMapping. However, #GetMapping is working fine with basic authentication
#PostMapping(value = { "/version" })
#ApiOperation(value = "Set Version")
#Monitor(useCase = "setApplicationVersion")
public void setApplicationVersion() {
System.out.println("Hey postman");
}
This is my #PostMapping method. Suggest something for the issue
Please post screenshot of what kind of request is being sent via postman and the type of content we are sending as same needs to be set at the controller level.
check if content type is set to application/json in the controller and when sending request from postman.

How to access the request body in SpringBoot's AccessDecisionVoter?

So we have a Authorisation server with which we create OAuth2 access token. All sub-systems verify the access token and may check the request path for permissions, however, in one of the sub-systems we need to look into the request body and extract the 'id' to check if the user has proper permission to submit the request. The request message is in JSON format and this is a POST request with client-provided id.
The id in the request is a process id and some users may not have right permission to some processes therefore we need the id to verify.
So while in AccessDecisionVoter, we only can get request URI but I can't get HttpServletRequest to read the message. (Note: We have a Request wrapper that allows us to read request body multiple times)
I tried to auto-wire HttpServletRequest, no luck. There is an error that no thread has been bound to the request
I was also thinking about implementing UserDetailService but again no luck as this is not being invoked by Spring boot. Remember that we are using a custom AuthorizationServerTokenServices and that is in a common library.
How do I get Http servlet request or the request body in AccessDecisionVoter?
You should be able to implement an AccessDecisionVoter<FilterInvocation> where you can get the request. Does this not work:
public class MyAccessDecisionVoter implements AccessDecisionVoter<FilterInvocation> {
#Override
public boolean supports(ConfigAttribute attribute) {
return false;
}
#Override
public boolean supports(Class<?> clazz) {
return true;
}
#Override
public int vote(Authentication authentication, FilterInvocation fi, Collection<ConfigAttribute> attributes) {
int result = ACCESS_ABSTAIN;
fi.getRequest() // this is the request
// decide the outcome and set result
return result;
}
}

POST request to Spring REST web service fails with HTTP status 415

I have set up a spring RESTful web service for taking in the username and password from a user. Been following the tutorial on Spring IO
My service is set up to accept user name and password as shown below:
#Controller
#RequestMapping("/users")
public class UserCommandController {
private static Logger log = LoggerFactory.getLogger(UserCommandController.class);
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity createUser(#RequestBody UserDetail userDetail, UriComponentsBuilder builder) {
User newUser = new User();
newUser.setEmail(userDetail.getEmail());
newUser.setPassword(userDetail.getPassword());
newUser.setUserName(userDetail.getUsername());
try {
UserFactory.getInstance().saveNewUser(newUser);
} catch(UserException ue) {
log.error("Saving user failed. Exception: "+ue.getMessage());
}
return new ResponseEntity(HttpStatus.OK);
}
}
I am sending POST parameters to the service as a test through Google chrome plugin POSTMAN but I get "HTTP: 415..The server refused this request because the request entity is in a format not supported by the requested resource for the requested method."
Does anyone have an idea what I am doing wrong ?
Set the header:
Content-Type=application/json
This solved my problem!
The HTTP 415 response code means that the server expected data posted with a different content type. It appears you simply posted a form with username, password and email as parameters. That would result in a content-type of application/x-www-form-urlencoded.
Try posting with a content-type of application/xml or application/json. In your post body, you will need to put your data in the corresponding format. For example, if you use application.xml, the XML body should look something like:
<userDetail>
<userName>xxx</userName>
<password>xxx</password>
<email>xxx</email>
</userDatail>
Of course the exact format (i.e. element names) depends on the XML bindings. In fact, whether or not the expected format is XML or JSON or something else is also likely a server configuration.
Posting a request of this type cannot easily be done with a browser. You will need some other HTTP client. A tool like SOAP-UI might be a good bet.

How can I create a dropwizard (jersey) resource which accepts a nullable representation?

I am trying to create an action on a resource within dropwizard which accepts a representation, but allows this to be null, ie. no post data from the client.
Currently, from a client, I have to post "{}" otherwise an HTTP 415, unsupported media type is returned. I assume this is because my client is not sending a content-type header as content-length = 0.
I tried to define the resources as follows, but get a "Producing media type conflict" back from jersey as both methods consume the same path and jersey cannot differentiate between them:
#Path("/interview")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#Log
class InterviewResource {
#POST
#Timed
Interview advanceNewInterview() {
// some processing...
}
#POST
#Timed
Enquiry advanceNewInterview(#Valid AdvanceInterviewRepresentation advanceInterview) {
// some processing...
}
}
Any ideas on how to represent this?
You could use Optional for your parameter as show below:
#POST
#Timed
Enquiry advanceNewInterview(#Valid Optional<AdvanceInterviewRepresentation> advanceInterview)
{
if (advanceInterview.isPresent())
{
// some processing...
}
}
Howerver the main Reason for 415 is not mentioning the Content-Type header. In your case it should be Content-Type : application/json

Resources