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

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());
}
});

Related

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

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?

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.

spring load resources conditionally

I want to use JS to load another JS file from a server but i want to do it conditionally example if the userId sent by the request is in my database send back the file.
So i thought of creating an interceptor.
Is there a better way to do it because an interceptor would be an overkill?
<mvc:interceptors>
<mvc:interceptor>
<bean class="com.mycomp.webservice.UserInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
public class UserInterceptor extends HandlerInterceptorAdapter {
#Autowired
UserService userService;
#Override
#Transactional
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if(!userService.userPresent(request)){
return false;
}
else{
return true;
}
}
Edit: So i figured out that the question isn't that clear. the file i want to upload is part of the static resources so i don' want to just load it to the client, i want to cache it as well.
So i leave you with a link.
Edit 2: So this is what i ended up doing. under my mvc-resources config i created an interceptor to handle request for protected static resources.
<mvc:resources mapping="/static/**" location="/static/" />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/static/protected/**" />
<bean class="com.mycompany.interceptor.ProtectedResourcesInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
public class ProtectedResourcesInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if("your condition is true") {
System.out.println("Access Granted to protected resources");
return true;
}
return false;
}
}
The interceptor will handle requests to /static/protected and if conditions are right it will serve it. If anyone has a cleaner solution please share it.

Params not sent from android to node.js using Volley

I am creating an app which uses some node.js scripts for server scripting mainly because node.js has Firebase support, but for some reason I am unable to send any params with my request (both GET and POST).
My android code is as follows
private void sendData(final String name){
StringRequest sr = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getApplicationContext(),response.toString()+" returned from node.js server",Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),error.toString()+"The Server returned error",Toast.LENGTH_SHORT).show();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String,String> map = new HashMap<>();
map.put("test",name);
return map;
}
};
RequestQueue r = Volley.newRequestQueue(getApplicationContext());
r.add(sr);
}
The corresponding node.js script is as follows
app.get('/hello', function(request, response){
var outputJson = request.params.test;
response.send(JSON.stringify(outputJson));
console.log(outputJson);
})
The console always logs undefined for some reason. Following suggestions from this post I also tried including the data in the body of the request and get the data from the request in the node.js via request.body.test.
I would like to know what is going wrong and most importantly I would also like to know how to recieve and process POST request. I read on some blog that I have to implement a middleware of some kind. Some clarification in that area will also be appreciated.
I have looked at your code and found that there are some flaws in the Android Code.
The HashMap is defined in a getHeaders() function but it should actually be defined in getParams() like this
#Override
public Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> map = new HashMap<>();
map.put("test",name);
return map;
}
Instead of trying to retrieve the data by request.params try using request.body.

Javascript function unable to make HTTP request

I have two different java projects and I need them to interact with each other. The first one named RESTfulWebServer is a dynamic web project which contains the basic HTTP GET PUT POST requests in a java class named UserServices. It just prints one line statements right now on console(output window in netbeans), so nothing complex.
The other project named ClientProject is also a dynamic web project which contains a simple jsp page containing javascript code. It is supposed to make call to the RESTfulWebServer project and print the output line on console(output window in netbeans) the same way the RESTfulWebServer project does when a simple GET request is made to it.
This is the part where the problem arises. When I run the ClientProject the javascript function is being called properly (as I checked by printing an alert message), but it is not making the DELETE HTTP request to the RESTfulWebServer as it is supposed to.
Both the codes are attached below:
RESTfulWebServer (UserServices.java)
package com.service.user;
import javax.ws.rs.*;
#Path("/user/service")
public class UserServices {
#GET
public void getUser()
{
System.out.println("Inside get user method");
}
#POST
public void updateUser()
{
System.out.println("Inside update user method");
}
#DELETE
public void deleteUser()
{
System.out.println("Inside DELETE user method");
}
}
ClientProject (clientfile.jsp)
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Update User</title>
<script>
function loadResponse()
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState === 4 && xmlhttp.status === 200)
{
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.open("DELETE","http://localhost:8080/app/user/service",true);
xmlhttp.send();
}
</script>
</head>
<body>
<div id="myDiv">The response text would come here</div>
<button type ="button" onclick="loadResponse()">submit</button>
</body>
</html>
The clientfile is supposed to print on console "Inside DELETE user method" but nothing is showed on console after "Build successful" message
What am I doing wrong? Also I am making use of TomCat server and doing this in NetBeans and I have to work on this IDE solely for some reason (kindly do not suggest to move to any other IDE and check it) if there is any mistake in my code or anything else pleaseee mention it?
First of all starting with requesting URL http://localhost:8080/app/user/service
when it falls in class level annotation - there are three methods so which one to pick so, needed to provide method level annotations as well for better approach.
#Path("/user/service")
public class UserServices {
#Path("/getUser")
#GET
public void getUser() { System.out.println("Inside GET method"); }
#Path("/updateUser")
#POST
public void updateUser() { System.out.println("Inside UPDATE method"); }
#Path("/deleteUser")
#DELETE
public void deleteUser() { System.out.println("Inside DELETE method"); }
}
Now coming towards something important which is necessary to make project(RestWebServer) accept requests from another project(Client Projects/app) which is hosted on separate domain, i.e. CORS (Cross Origin Resource Sharing)
CORS, in a nutshell, is a security check implemented like when an application requests for resources from or make server calls to another domain, these requests get blocked by browsers. Moreover you are using XMLHttpRequest which forces same-origin policy i.e. request should generate from same domain where resources are residing so in order to make requests allow cross domain accessing we implement CORS Filter logic on server side to allow methods (P,G,P,D) to get executed.
So add a class like this in your WebService Project in package where UserServices class is:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CORSFilter implements Filter {
public CORSFilter() { }
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
((HttpServletResponse)response).addHeader("Access-Control-Allow-Origin", "*");
((HttpServletResponse)response).addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
chain.doFilter(request, response);
}
}
Now time to use this Filter in web.xml
<web-app ....>
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class><package name -must be complete>.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
clientFile.jsp
Now call method like this from view page with just method annotation added
xmlhttp.open('DELETE','http://localhost:8080/app/user/service/deleteUser',true);
Last thing you will have to make two server instances of Tomcat to deploy, name them Service and Client Server respectively for your convenience while making them. Let the Service one have all default config but you will have to change all three Port number for Client Server to avoid binding error. For this simply double click on server (Client) see Ports heading and change ports.
All done, it should run now, tested as well. Hope this will help you and other thread readers as well.

Categories