What error should server respond with when client sends invalid uuid? - javascript

I am developing microservice using spring boot. This service generates uuid and sends it to the client when he enters to app, and client saves uuid in cookie. Now when client makes request to resource there is a filter that check if uuid is valid.
#Override
public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
throws IOException, ServletException {
String uuid = req.getParameter("guest_uuid");
if (isValidUUID(uuid)){
chain.doFilter(req, res);
}else {
// respond with customer error
}
}
What error should server respond with so that client side(javascript) could identify this error and remove uuid from cookie?

Related

Disable Sign In Window in Spring (Http Basic) [duplicate]

This question already has answers here:
Disable browser authentication dialog in spring security
(3 answers)
Closed 1 year ago.
I'm creating a simple app with a Sign-In site.
I used HTTP basic type of authorization, but the problem is I don't know how to disable the pop-up window which is showing every time when I pass wrong credentials or in case of writing secured endpoint site before authentication.
The frontend is written in pure JS, launched without any template engine. Just js + html files in static dir.
The authentication page uses the Fetch Api to send headers with credentials
Does someone knows how to disable this window, shown below:
Here is my Security config class:
#Configuration
#EnableWebSecurity
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
#Resource
private UserDetailsService userDetailsService;
#Autowired
private CustomLogoutHandler logoutHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, "/demo/users/save").permitAll()
.antMatchers(HttpMethod.POST, "/demo/users/**").permitAll()
.antMatchers(HttpMethod.POST, "/users/*/save").permitAll()
.antMatchers(HttpMethod.DELETE, "/users/**").permitAll()
.antMatchers(HttpMethod.POST, "/users/*/verify").permitAll()
.antMatchers(HttpMethod.GET,"/users/**").permitAll()
.antMatchers(HttpMethod.PUT,"/users/**").permitAll()
.antMatchers("/css/**", "/js/**", "/img/**").permitAll()
.antMatchers("/signup-page.html").permitAll()
.antMatchers("/landing-page.html").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.disable()
.logout()
.logoutUrl("/logout")
.addLogoutHandler(logoutHandler)
.logoutSuccessUrl("/landing-page.html")
.logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))
.permitAll()
.and()
.httpBasic();
}
#Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
I couldn't find the answer before, every response I found consisted of "disable httpBasic" and that wasn't a satisfying solution.
Here is a Topic :
Spring Boot security shows Http-Basic-Auth popup after failed login
and these lines solved my problem:
httpBasic()
.authenticationEntryPoint(new AuthenticationEntryPoint(){ //<< implementing this interface
#Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
//>>> response.addHeader("WWW-Authenticate", "Basic realm=\"" + realmName + "\""); <<< (((REMOVED)))
response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());
}
});

Cross-Origin Request Blocked when making post request to ASP.NET Core Web API

I have a Web API that has 2 controllers and I have enabled Cors in my Startup class, here is my ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
services.AddAutoMapper();
}
And here the Configure medhod:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors(
options => options.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
app.UseHttpsRedirection();
app.UseMvc();
}
Now, I have two controllers. When I make a GET request to this method, everything goes ok:
[Route("api/[controller]")]
[ApiController]
[EnableCors("MyPolicy")]
public class MovieController : ControllerBase
{
public async Task<IActionResult> Get()
{
HttpClient httpClient = new HttpClient();
var responseMessage = await httpClient.GetAsync("https://copafilmes.azurewebsites.net/api/filmes");
if (!responseMessage.IsSuccessStatusCode) return null;
var jsonResult = await responseMessage.Content.ReadAsStringAsync();
return Ok(jsonResult);
}
Now, when I try to make a POST to this one:
[Route("api/[controller]")]
[ApiController]
[EnableCors("MyPolicy")]
public class CupController : ControllerBase
{
private readonly IMapper mapper;
public CupController(IMapper mapper)
{
this.mapper = mapper;
}
[HttpPost]
public IActionResult Post([FromBody] IEnumerable<MovieViewModel> moviesViewModel)
{
var movies = mapper.Map<IEnumerable<Movie>>(moviesViewModel).ToList();
var cup = new Cup(movies);
cup.Run();
return Ok(cup.Id);
}
}
Then I get the message in the browser console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://worldcupapi-gabs.azurewebsites.net/api/cup. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
I am trying to make this post via a Vuejs simple app, you can try it here: https://codesandbox.io/s/j23np20663
Just select 8 cards (click on them and they'll become grey) and click on the "Submit" button.
Serpent5 provided a valid answer above; I'm adding it as an answer because this is the first hit I got when searching on my CORS issue AND the cause of my issue isn't precisely what Serpent5 indicated, but expanding on his comment provides the answer.
Serpent5's answer basically says another error is preventing the server from responding properly (such as a 500 internal server error), but the browser development tools console shows a CORS error instead.
In my case it was because I didn't have https configured correctly on the server.

Access to WCF WebService from JavaScript - Response to preflight request doesn't pass access control check

I am using a WCF (.svc) WebService and it's working perfectly - I can call its methods without problems from Postman, PHP, etc. But, when I try to call it from JavaScript/jQuery using AJAX, there is an obvious problem - I do it from other domain than WS, so it won't let me do it.
It is all about POST methods. But there is a problem even when my page is sending firstly an OPTIONS method:
OPTIONS 'WS ADDRESS' 405 (Method Not Allowed)
XMLHttpRequest cannot load 'WS ADDRESS' Response to preflight request doesn't
pass access control check: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'MY ADDRESS' is therefore not allowed
access. The response had HTTP status code 405.
There are detailed responses:
Okay, I read about cross-domain and WS's Web.config contains all of it that is necessary (?)
Please let me know what am I doing wrong that I cannot reach my WS from JavaScript, even though it seems to me configured well. But still, it seems not to send these special headers in response... Thanks in advance.
XML HttpRequest allows data to be transferred from a web server to the browser. The browsers, however, prevents CORS by default.
GET request is not going to change anything on the server side (nothing is created/updated/deleted) - it's only going to return some data.
POST/PUT/DELETE requests, however, will process the request and change something on the server side and issue a response to the browser. If the response doesn't have a proper Access-Control-Allow-Origin header, the browser will block the response. But that doesn't matter because by the time the response is issued, the server has already processed the request and made changes, perhaps to a database.
In order to prevent POST/PUT/DELETE request to be processed on server side, browsers will send a preflight request.
A prefligth request is an http request with the method OPTIONS. So before sending the POST request, the browser will send an OPTIONS request with an additional header called Access-Control-Request-Method with the value of POST.
The 405 (Method Not Allowed) error indicates the the server is not configured to accept OPTIONS request.
You can solve this issue either by using a wildcard for your web invoke method similar to this:
[OperationContract]
[WebInvoke(Method = "*", UriTemplate = "/Path", ResponseFormat = WebMessageFormat.Json)]
Or by adding an additional [OperationContract] to your [ServiceContract] that handles OPTIONS request similar to this:
[OperationContract(Name = "OptionsMyFunction")]
[WebInvoke(Method = "OPTIONS", UriTemplate = "/Path", ResponseFormat = WebMessageFormat.Json)]
You can implement .NET IDispatchMessageInspector for this work.
Create a class implementing IDispatchMessageInspector
Create a class implementing Attribute,IEndpointBehavior,IOperationBehavior
Allow only OPTIONS in your class implementing IDispatchMessageInspector
The code will look like this
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Net;
namespace WapstyPrintService
{
public class MessageInspector : IDispatchMessageInspector
{
private ServiceEndpoint _serviceEndpoint;
Dictionary<string, string> requiredHeaders;
public MessageInspector(ServiceEndpoint serviceEndpoint)
{
_serviceEndpoint = serviceEndpoint;
requiredHeaders = new Dictionary<string, string>();
requiredHeaders.Add("Access-Control-Allow-Origin", "*");
requiredHeaders.Add("Access-Control-Request-Method", "POST,GET,PUT,DELETE,OPTIONS");
requiredHeaders.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");
}
/// <summary>
/// Called when an inbound message been received
/// </summary>
/// <param name="request">The request message.</param>
/// <param name="channel">The incoming channel.</param>
/// <param name="instanceContext">The current service instance.</param>
/// <returns>
/// The object used to correlate stateMsg.
/// This object is passed back in the method.
/// </returns>
public object AfterReceiveRequest(ref Message request,
IClientChannel channel,
InstanceContext instanceContext)
{
var httpRequest = (HttpRequestMessageProperty)request
.Properties[HttpRequestMessageProperty.Name];
return new
{
origin = httpRequest.Headers["Origin"],
handlePreflight = httpRequest.Method.Equals("OPTIONS",
StringComparison.InvariantCultureIgnoreCase)
};
}
/// <summary>
/// Called after the operation has returned but before the reply message
/// is sent.
/// </summary>
/// <param name="reply">The reply message. This value is null if the
/// operation is one way.</param>
/// <param name="correlationState">The correlation object returned from
/// the method.</param>
public void BeforeSendReply(ref Message reply, object correlationState)
{
var state = (dynamic)correlationState;
if (state.handlePreflight)
{
reply = Message.CreateMessage(MessageVersion.None, "PreflightReturn");
var httpResponse = new HttpResponseMessageProperty();
reply.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
httpResponse.SuppressEntityBody = true;
httpResponse.StatusCode = HttpStatusCode.OK;
}
var httpHeader = reply.Properties["httpResponse"] as HttpResponseMessageProperty;
foreach (var item in requiredHeaders)
{
httpHeader.Headers.Add(item.Key, item.Value);
}
}
}
}
and
using System;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
namespace WapstyPrintService
{
public class BehaviorAttribute : Attribute, IEndpointBehavior,
IOperationBehavior
{
public void Validate(ServiceEndpoint endpoint) { }
public void AddBindingParameters(ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{ }
/// <summary>
/// This service modify or extend the service across an endpoint.
/// </summary>
/// <param name="endpoint">The endpoint that exposes the contract.</param>
/// <param name="endpointDispatcher">The endpoint dispatcher to be
/// modified or extended.</param>
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
// add inspector which detects cross origin requests
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(
new MessageInspector(endpoint));
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{ }
public void Validate(OperationDescription operationDescription) { }
public void ApplyDispatchBehavior(OperationDescription operationDescription,
DispatchOperation dispatchOperation)
{ }
public void ApplyClientBehavior(OperationDescription operationDescription,
ClientOperation clientOperation)
{ }
public void AddBindingParameters(OperationDescription operationDescription,
BindingParameterCollection bindingParameters)
{ }
}
}
Then add your message inspector to service endpoint behavior
ServiceHost host = new ServiceHost(typeof(myService), _baseAddress);
foreach (ServiceEndpoint EP in host.Description.Endpoints)
EP.Behaviors.Add(new BehaviorAttribute());

XMLHTTPRequest error when integrating log4js AjaxAppender with Java backend

I am trying to do some frontend logging using log4js and sending the logs using the AjaxAppender to the server backend using Java. This is the frontend code that I use to initialize the logger, I've made sure the logger works with a DefaultLogger, and switched to AjaxAppender.
var log = log4javascript.getLogger();
var ajaxAppender = new log4javascript.AjaxAppender("logger");
ajaxAppender.setTimed(true);
ajaxAppender.setTimerInterval(10000); // send every 10 seconds (unit is milliseconds)
log.addAppender(ajaxAppender);
//convert to JSON format
jsonLayout = new log4javascript.JsonLayout(false, false); //readable, combineMessages
ajaxAppender.setLayout(jsonLayout);
ajaxAppender.addHeader("Content-Type", "application/json");
log.info("Begin Session")
This is the backend code written in Java, which gets the logs sent from the frontend.
#RequestMapping(value = "/logger", method = RequestMethod.POST)
#ResponseBody
public String logger(HttpServletRequest request, HttpServletResponse response) throws InterruptedException, IOException, SQLException {
System.out.println("Inside Logger");
System.out.println("Log:"+request);
return "Test successful:" + request;
}
However, I am getting the error XHR failed loading POST and the code doesn't seem to go inside the logger function ("Inside Logger" is not printed in terminal). I'm fairly new to working with Ajax and sending request between frontend and backend, is there a reason why the XMLHttpRequest is not going through?
Thanks!
404 means the service isn't reachable. Are you sure you've started the service and configged it properly?

WebSocket clients from one external ip address

I wrote a chat through WebSockets.
Server side is written in Java (Tomcat) and client in JavaScript.
All works fine. But when I try connect to server from two machines which are in local network (they're under router; have one external ip) only one client receives data from server.
Connection ( socket.onopen() ) works for both. socket.send(data) also works on both clients;
But receiving messages ( socket.onmessage() ) works just on first connected client.
How can I resolve this problem?
Problem was in server part.
I wanted to broadcast incoming message to all available connections which were in ArrayList.
After sending message to first user, received message became emptied. So, message was sent, but it was just empty string.
My english is bad. So I will whow :
before :
protected void onTextMessage(CharBuffer message) throws IOException {
// List<MessageInbound> connections
for (MessageInbound user : connections )
user.getWsOutbound.writeTextMessage(message);
}
after:
protected void onTextMessage(CharBuffer message) throws IOException {
String msg = message.toString();
for (MessageInbound user : connections )
user.getWsOutbound.writeTextMessage(CharBuffer.wrap(msg));
}

Categories