Browser not prompting for credentials using basic authentication - jax-rs

My goal is to provide authentication to a single resource on the server, for this I am using custom filter. I am not using #NameBinding because of constraint of using JAVA 1.6.Using Response.header(HttpHeaders.WWW_AUTHENTICATE,"Basic") is not prompting for credentials.
Using ContainerRequestFilter is not helping my cause as it will put filter on every resource of server.
Filter
#Provider
public class AuthenticationFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
System.out.println("Entered authentication filter");
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.AUTHORIZATION,"Basic")
.entity("Credentials are required to access this resource.")
.build());
// chain.doFilter(req, resp);
}
#Override
public void init(FilterConfig arg0) throws ServletException {}
#Override
public void destroy() {}
}
web.xml mapping
<filter>
<filter-name>AuthenticationFilter</filter-name>
<filter-class>Utils.LDAPAuthentication.AuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/download</url-pattern>
</filter-mapping>
The response I am getting on hitting the webservice is

So as suggested by Paul , I used HttpServletResponse.
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getHeader("Authorization")==null){
response.setHeader(HttpHeaders.WWW_AUTHENTICATE,"Basic");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
else{
String credentials = request.getHeader("Authorization");
}

Related

Error: No 'Access-Control-Allow-Origin' header is present on the requested resource. even after including the CORS support

I am trying to write an Api in spring boot and am trying to access it using frontend I have written.
I have added the Cors support, still I am getting this error:
*
Failed to load http://localhost:8080/: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
My Cors support in main file is:
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/greeting-javaconfig").allowedOrigins("*");
}
};
}
I am using apache server for frontend.
Can sopmeone help me with the issue?
To enable CORS in spring-boot you need to add the following filter class in your spring-boot application.
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
response.setHeader("Access-Control-Expose-Headers", "WWW-Authenticate");
}
#Override
public void init(FilterConfig filterConfig) {
}
#Override
public void destroy() {
}
}

Cant get authentication filter working with embedded jetty

I have a REST handler servlet defined as follows (this works perfectly):
//REST handler context
ServletContextHandler restHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
restHandler.setContextPath("/");
// Jersey REST handling servlet
ServletHolder jerseyServlet = restHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tell Jersey which REST service class to load....
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", RestHandler.class.getCanonicalName());
I now want to add a authentication filter, which I do as:
FilterHolder authFilter = restHandler.addFilter(AuthFilter.class, "/",
EnumSet.of( DispatcherType.ASYNC,
DispatcherType.ERROR,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.REQUEST));
if (authFilter == null) {
dlog.debug("Failed to load authentication filter");
};
All good so far, however, the filter does not fire on incoming REST. Calls still go through. The AuthFilter is straight from sample code:
public class AuthFilter implements javax.servlet.Filter {
private static final Logger dlog = Dlog.get();
public static final String AUTHENTICATION_HEADER = "Authorization";
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter)
throws IOException, ServletException {
dlog.entry(request, response, filter);
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String authCredentials = httpServletRequest.getHeader(AUTHENTICATION_HEADER);
AuthService authenticationService = new AuthService();
boolean authenticationStatus = authenticationService.authenticate(authCredentials);
if (authenticationStatus) {
filter.doFilter(request, response);
} else {
if (response instanceof HttpServletResponse) {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}
dlog.exit();
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig arg0) throws ServletException {
}
}
I use handler collection as I also have a resource handler to serve static web pages besides the REST calls.
HandlerCollection handlerList = new HandlerCollection();
handlerList.setHandlers(new Handler[] { resourceHandler,
restHandler,
new DefaultHandler(),
requestLogHandler });
What else I need to do? I have scanned through number of related posts and come up empty. Thanks in advance.

NoSuchMethodError error when invoking projectListRequest.execute() method

I am trying to develop a simple BigQuery App using JSP Servlets. I am following the exampla given on https://developers.google.com/bigquery/docs/authorization
In the early stages, the doGet method was not getting invoked and so I overrided the Service method. The code looks like this
public class BigQueryWebServerAuthDemo extends AbstractAuthorizationCodeServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
System.out.println(" Start service ");
doGet(req, resp);
}
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
System.out.println(" Start doGet ");
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
System.out.println(" Start doPost ");
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
System.out.println(" Begin loadbigquery() ");
Bigquery bigquery = CredentialUtils.loadbigquery();
System.out.println(" end loadbigquery() ");
Bigquery.Projects.List projectListRequest = bigquery.projects().list();
ProjectList projectList = projectListRequest.execute();
if (projectList.getProjects() != null) {
java.util.List<Projects> projects = projectList.getProjects();
writer.println("<h3>BigQuery project list:</h3>");
for (ProjectList.Projects project : projects) {
writer.printf("%s<br />", project.getProjectReference().getProjectId());
}
}
System.out.println(" End doPost ");
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws ServletException, IOException {
System.out.println(" inside BigQueryWebServerAuthDemo --- initializeFlow() ");
return CredentialUtils.newFlow();
}
#Override
protected String getRedirectUri(HttpServletRequest request) throws ServletException, IOException {
System.out.println(" inside BigQueryWebServerAuthDemo --- getRedirectUri() ");
return CredentialUtils.getRedirectUri(request);
}
#Override
protected String getUserId(HttpServletRequest request) throws ServletException, IOException {
System.out.println(" inside BigQueryWebServerAuthDemo --- getUserId ");
return request.getParameter("userId");
}
}
I have a JSP page from where I am getting the parameter "userId". Now I get a
NoSuchMethodError on execute() method [projectListRequest.execute()] though Eclipse compiler doesnt show any error.
Below is my web.xml config info
<servlet>
<servlet-name>oauth2callback</servlet-name>
<servlet-class>main.BigQueryWebServerAuthCallBack</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>oauth2callback</servlet-name>
<url-pattern>/oauth2callback</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ServletBigQuery</servlet-name>
<servlet-class>main.BigQueryWebServerAuthDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletBigQuery</servlet-name>
<url-pattern>/ServletBigQuery</url-pattern>
</servlet-mapping>
I have 2 more classes CredentialUtils and BigQueryWebServerAuthCallBack as given in the tutorial mentioned above.
I am actually new to Java . I want get rid of the NoSuchMethodError error. Any help will be greatly appreciated.

Authentication filter and servlet for login

I've a filter used for the login. It performs a textual checking, on fields "Username" and "Password". If and only if the textual checking is correctly done the request goes to the Servlet. This latter performs the control that has to interact with the Database. Is this chain correct?
Preface: I gather you're using homegrown login instead of container managed login. For all ways, see How to handle authentication/authorization with users in a database?
The filter (the interceptor) shouldn't check the validity of the username/password combo. That's the responsibility of the servlet (the controller).
The filter should merely check if the user is logged-in or not (usually by just checking the presence of a session attribute) and then continue the request or block it by redirecting back to the login page.
#WebFilter("/*")
public class LoginFilter implements Filter {
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
HttpSession session = request.getSession(false);
String loginURI = request.getContextPath() + "/login";
boolean loggedIn = session != null && session.getAttribute("user") != null;
boolean loginRequest = request.getRequestURI().equals(loginURI);
if (loggedIn || loginRequest) {
chain.doFilter(request, response);
} else {
response.sendRedirect(loginURI);
}
}
// ...
}
The servlet should collect the submitted data, find the associated User in database and if found then store it as a session attribute and then redirect to the home page, else redisplay the form with validation errors.
#WebServlet("/login")
public class LoginServlet extends HttpServlet {
#EJB
private UserService userService;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
Map<String, String> messages = new HashMap<String, String>();
if (username == null || username.isEmpty()) {
messages.put("username", "Please enter username");
}
if (password == null || password.isEmpty()) {
messages.put("password", "Please enter password");
}
if (messages.isEmpty()) {
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath() + "/home");
return;
} else {
messages.put("login", "Unknown login, please try again");
}
}
request.setAttribute("messages", messages);
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
}
See also:
Our servlet-filters wiki page
Our servlets wiki page

Redirecting a user after container-based login using JAAS and JSF

I'm trying to accomplish a jsf2-based form login where a user can go straight to his chosen URL after being redirected to the login-page. How can this be accomplished? My current settings are as following (using glassfish 3)
Web.XML
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsf</form-login-page>
<form-error-page>/login.jsf</form-error-page>
</form-login-config>
</login-config>
<security-constraint> //(omitted) all pages except login.jsf requires login </security-constraint>
Session scoped managed bean handling login
public String login(){
try{
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
request.login(username, pwd);
loggedInUser = userBean.findByLogin(username);
username = null;
pwd = null;
//context.getExternalContext().redirect((String)request.getAttribute("from"));
return "/index?faces-redirect=true";
} catch(Exception e){
logger.log(Level.FINE, "login failed: {0}", e.getMessage());
JsfUtil.addErrorMessage("Login failed");
return null;
}
}
From another question i got the tip to use a filter instead of the contained handled redirect to the login page, and store the URL before redirect as an attribute in the request like this:
public class LoginFilter implements Filter {
private String loginPage = "/login.jsf";
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,
ServletException {
if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// is session expire control required for this request?
if (httpServletRequest.getUserPrincipal() == null) {
// User is not logged in, redirect to login page.
httpServletRequest.setAttribute("from", httpServletRequest.getRequestURI());
httpServletResponse.sendRedirect(loginPage);
}
else
filterChain.doFilter(request, response);
}
}
#Override
public void destroy() {
}
}
With the url-pattern set to the same as the sum of all security constraints. The problem is how to combine this with the container based login. Leaving login-config auth method as FORM causes the filter to not be executed. Removing it sets the auth-method to BASIC which 1. causes my form to not appear, and 2. httpServletRequest.getUserPrincipal() is automatically set by the web browser to a cached value, so even if the filter is executed, the if-statement will always be false. From what i know, there is no way to keep the browser from doing this, even if the session is invalidated.
Is there any solution to this?