SAPUI5 to Java HttpServletRequest.getUserPrincipal() returns null - java

I'm trying to authenticate users in my java backend. I'm trying to connect to my backend with SAPUI5. I added two roles in the SCP Portal and I want to access them in Java. I'm using HttpServletRequest.getUserPrincipal() to get the user, but it keeps returning null. Any ideas on how to solve this? Did I forget something in SAPUI5?
package be.amista.filters;
import java.io.IOException;
import java.security.Principal;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sap.security.um.service.UserManagementAccessor;
import com.sap.security.um.user.User;
import com.sap.security.um.user.UserProvider;
#WebFilter("/*")
public class UserFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(UserFilter.class);
private static Set<String> userRoles;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.getUserPrincipal() != null) {
try {
// UserProvider provides access to the user storage
UserProvider users = UserManagementAccessor.getUserProvider();
// Read the currently logged in user from the user storage
User user = users.getUser(httpServletRequest.getUserPrincipal().getName());
userRoles = user.getRoles();
} catch (Exception e) {
// Handle errors
logger.error(e.getMessage());
}
}
// pass the request along the filter chain
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
public static Set<String> getUserRoles() {
return userRoles;
}
}

I found a solution myself. I added this piece of code to the web.xml and it worked.
<resource-ref>
<res-ref-name>user/Provider</res-ref-name>
<res-type>com.sap.security.um.user.UserProvider</res-type>
</resource-ref>
<resource-ref>
<res-ref-name>connectivityConfiguration</res-ref-name>
<res-type>com.sap.core.connectivity.api.configuration.ConnectivityConfiguration</res-type>
</resource-ref>
<login-config>
<auth-method>FORM</auth-method>
</login-config>
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>Everyone</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<description>All SAP Cloud Platform users</description>
<role-name>Everyone</role-name>
</security-role>

Related

A servlet that was working before with certificate authentication was changed and is now throwing exceptions

A Java servlet application has been changed so that it no longer requires certificate authentication.
That part works correctly. However, the application no longer connects to the database and throws the following exception:
> REMOTE USER IS null MY URL is 0:0:0:0:0:0:0:1 NULL GENERICPRINCIPAL
> Apr 01, 2021 12:43:11 PM org.apache.catalina.core.StandardWrapperValve
> invoke SEVERE: Servlet.service() for servlet
> [com.harris.cpd.resource.ApplicationConfig] in context with path
> [/cpd] threw exception [java.lang.NullPointerException] with root
> cause java.lang.NullPointerException at
> com.harris.cpd.resource.CPDResource.getTomcatUserRole(CPDResource.java:116)
The following is web.xml with changes shown in comments.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>cpd</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>chemicals.html</welcome-file>
</welcome-file-list>
<!-- THIS IS NEW CODE -->
<filter>
<filter-name>CPDAuthenticationFilter</filter-name>
<filter-class>com.harris.cpd.filter.CPDAuthenticationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CPDAuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- THIS SECTION IS NEW CODE -->
<servlet>
<servlet-name>cpd</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>cpd</servlet-name>
<url-pattern>/cpd/*</url-pattern>
</servlet-mapping>
<!-- THIS SECTION IS NOW COMMENTED OUT
<security-constraint>
<web-resource-collection>
<web-resource-name>BasicSecurity</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<description>Authorized role is librarian</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>BasicSecurity</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
</web-resource-collection>
<auth-constraint>
<description>Authorized role is guest and librarian</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
<role-name>DOMAIN_GUEST</role-name>
</auth-constraint>
</security-constraint> -->
<!-- THIS IS NEW CODE AND PROVIDES THE BASIC LOGIN -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Login</realm-name>
</login-config>
<!-- THIS CODE IS NOW COMMENTED OUT
<login-config>
<auth-method>CLIENT-CERT</auth-method>
<realm-name>IAASecurityRealm</realm-name>
</login-config> -->
<security-role>
<description>A Guest User in the system</description>
<role-name>DOMAIN_GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>DOMAIN_LIBRARIAN</role-name>
</security-role>
<!--
<security-role>
<description>A Guest User in the system</description>
<role-name>GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>LIBRARIAN</role-name>
</security-role>
-->
</web-app>
And here is CPDAuthenticationFilter.java which is the filter code.
One line was deleted below:
UserRole role = auth.authenticate(authCredentials);
The following line replaced it, hard-coding "role":
UserRole role = UserRole.DOMAIN_LIBRARIAN;
package com.harris.cpd.filter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.harris.cpd.authentication.AuthenticationService;
import com.harris.cpd.authentication.UserRole;
//#WebFilter(filterName="authentication", urlPatterns="/resources/*")
public class CPDAuthenticationFilter implements Filter {
private final static Logger logger = Logger.getLogger(CPDAuthenticationFilter.class.getPackage().getName());
public static final String AUTHENTICATION_ATTR = "cpd.authenticate";
public static final String USER_ROLE_ATTR = "cpd.user.role";
/* (non-Javadoc)
* #see javax.servlet.Filter#destroy()
*/
#Override
public void destroy() {
}
/* (non-Javadoc)
* #see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filter)
throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.isUserInRole(UserRole.DOMAIN_GUEST.toString())) {
logger.log(Level.INFO, "found a guest user");
}
else if (httpServletRequest.isUserInRole(UserRole.DOMAIN_LIBRARIAN.toString())) {
logger.log(Level.INFO, "found a domain_librarian user");
}
else {
logger.log(Level.INFO, "found invalid user: "+httpServletRequest.getRemoteUser());
}
String authCredentials = httpServletRequest.getHeader(AUTHENTICATION_ATTR);
AuthenticationService auth = new AuthenticationService();
// CRM : TEST access 8080 without login:
//UserRole role = auth.authenticate(authCredentials);
UserRole role = UserRole.DOMAIN_LIBRARIAN; //CGN 3-25 TURNING OFF WHAT CHRIS HAD
logger.log(Level.INFO, "user role: " + role);
if (role.equals(UserRole.DOMAIN_GUEST) || role.equals(UserRole.DOMAIN_LIBRARIAN)) {
request.setAttribute(USER_ROLE_ATTR, role);
filter.doFilter(request, response);
} else {
if (response instanceof HttpServletResponse) {
logger.log(Level.INFO, "failed BASIC authentication");
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
}
}
}
/* (non-Javadoc)
* #see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
#Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("init the authentication filter (RestAuthenticationFilter)");
}
}
The errors that shows up on the Chrome debug tools for the client side:
-- LOADING APP (index.html) --
:8080/cpd/resources/categories:1 Failed to load resource: the server responded with a status of 500 ()
angular.js:14516 -- db: getProcessCategories url:http://localhost:8080/cpd/resources/categories procCats 500 failed --
So the problem presents itself as servlet error, and the database is not connecting, returning anything, with just the changes I have shown above.
I don't think this exception was related to database connection.
according to the exception which you have faced.
getTomcatUserRole(CPDResource.java:116)
I think there is another class like CPDResource.java that has been affected by this change
<!--
<security-role>
<description>A Guest User in the system</description>
<role-name>GUEST</role-name>
</security-role>
<security-role>
<description>A Guest User in the system</description>
<role-name>LIBRARIAN</role-name>
</security-role>
-->
and you should set it as a hardcode instead of getting from roles as before.

cannot Inject Named bean into javax.ws.rs class while #EJB could be used

I try to inject a named bean into a class using javax.ws.rs.* and got the result of :
javax.servlet.ServletException: A MultiException has 1 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=UserBean,parent=NameCheckREST,qualifiers={},position=-1,optional=false,self=false,unqualified=null,903092946)
root cause
So I can guess the dependency injection failed. After I comment the #inject and related methods, it works. My question is why I cannot inject the named bean into javax REST class while my teacher uses #EJB to inject ejb and it succeeds.
Is this kind of design mechanism? You can refer to the code below:
#inject failed:
package restServices;
import java.text.DecimalFormat;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObjectBuilder;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import beans.UserBean;
#Path("checkname")
public class NameCheckREST {
#SuppressWarnings("unused")
#Context
private UriInfo context;
#Inject
private UserBean userBean;
/**
* Default constructor.
*/
public NameCheckREST() {
// TODO Auto-generated constructor stub
}
// /**
// * Retrieves representation of an instance of NameCheckREST
// * #return an instance of String
// */
// #GET
// #Produces("application/json")
// public String getJson() {
// // TODO return proper representation object
// throw new UnsupportedOperationException();
// }
/**
* Retrieves representation of an instance of HelloWorld
* #return an instance of String
*/
#GET
#Produces("text/html")
public String getHtml() {
// TODO return proper representation object
//DecimalFormat df = new DecimalFormat("0.00");
return "<html><body><h1>" + "Web resources for CMS" + "</h1> </body></html>";
//throw new UnsupportedOperationException();
}
/**
* PUT method for updating or creating an instance of NameCheckREST
* #param content representation for the resource
* #return an HTTP response with content of the updated or created resource.
*/
#PUT
#Consumes("application/json")
public void putJson(String content) {
}
#POST
#Path("user")
#Consumes("application/x-www-form-urlencoded")
#Produces(MediaType.APPLICATION_JSON)
public JsonArray checkUsername(#FormParam("account") String account) {
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
objectBuilder.add("account", account);
if(userBean.searchUserByAccount(account) == null) {
objectBuilder.add("exist", false);
}else {
objectBuilder.add("exist", true);
}
arrayBuilder.add(objectBuilder);
return arrayBuilder.build();
}
}
named user bean:
package beans;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.util.logging.Level;
import java.util.logging.Logger;
import entity.NormalUser;
//import entity.User;
import repository.UserRepository;
#Named(value = "userBean")
#SessionScoped
public class UserBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#EJB
UserRepository userRepository;
//default constructor
public UserBean() {
}
public List<NormalUser> getAllUsers(){
try {
List<NormalUser> users = userRepository.getAllUsers();
//System.out.print("users:" + users.size());
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, "users:" + users.size());
return users;
} catch(Exception ex) {
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public boolean addUser(NormalUser user) {
try {
userRepository.addUser(user);
return true;
}catch (Exception ex) {
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public boolean removeUser(String account) {
try {
userRepository.deleteUser(account);
return true;
}catch (Exception ex) {
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public boolean editUser(NormalUser user) {
try {
userRepository.updateUser(user);
return true;
}catch (Exception ex) {
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
public NormalUser searchUserByAccount(String account) {
try {
NormalUser user = userRepository.searchUser(account);
return user;
}catch (Exception ex) {
Logger.getLogger(UserBean.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
#EJB succeed:
package helloworld;
import java.text.DecimalFormat;
import javax.ejb.EJB;
import javax.el.ELContext;
import javax.faces.context.FacesContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import calculator.LoanBean;
#Path("greeting")
public class HelloWorld {
#SuppressWarnings("unused")
#Context
private UriInfo context;
#EJB
private NameStorageBean nameStorage;
#EJB
private LoanBean loanBean;
/**
* Default constructor.
*/
public HelloWorld() {
// TODO Auto-generated constructor stub
}
/**
* Retrieves representation of an instance of HelloWorld
* #return an instance of String
*/
#GET
#Produces("text/html")
public String getHtml() {
// TODO return proper representation object
DecimalFormat df = new DecimalFormat("0.00");
return "<html><body><h1>Hello " + nameStorage.getName() + ", the monthly payment is " + df.format(loanBean.calculate()) +"!</h1> </body></html>";
//throw new UnsupportedOperationException();
}
#POST
#Consumes("application/x-www-form-urlencoded")
public void setPostName( #FormParam("name") String content) {
nameStorage.setName(content);
}
#POST
#Path("loan")
#Consumes("application/json")
public void setPostLoan(Loan loan) {
loanBean.setPrinciple(loan.getPrinciple());
loanBean.setInterestRate(loan.getInterestRate());
loanBean.setNumberOfYears(loan.getNumberOfYears());
loanBean.setMonthlyPayment(loanBean.calculate());
// ELContext context
// = FacesContext.getCurrentInstance().getELContext();
// WebServiceBean currentWebBean = (WebServiceBean) FacesContext.getCurrentInstance().getApplication()
// .getELResolver().getValue(context, null, "webServiceBean");
// currentWebBean.setMonthlyPayment(loanBean.calculate());
}
/**
* PUT method for updating or creating an instance of HelloWorld
* #param content representation for the resource
* #return an HTTP response with content of the updated or created resource.
*/
#PUT
#Consumes("text/html")
public void putHtml(String content) {
}
}
about web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<display-name>CMS-war</display-name>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<!-- <context-param>
<param-name>primefaces.THEME</param-name>
<param-value>bootstrap</param-value>
</context-param> -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/webresources/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>AdminContstraint</display-name>
<web-resource-collection>
<web-resource-name>WebResource</web-resource-name>
<url-pattern>/faces/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
<description>Administrator</description>
<role-name>Admin</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<display-name>NormalContstraint</display-name>
<web-resource-collection>
<web-resource-name>WebResource</web-resource-name>
<url-pattern>/faces/normal/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>DELETE</http-method>
<http-method>PUT</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
<description>NormalUser</description>
<role-name>Normal</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>cms_security</realm-name>
<form-login-config>
<form-login-page>/faces/login.xhtml</form-login-page>
<form-error-page>/faces/error.xhtml</form-error-page>
</form-login-config>
</login-config>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<security-role>
<description>Administrator</description>
<role-name>Admin</role-name>
</security-role>
<security-role>
<description>NormalUser</description>
<role-name>Normal</role-name>
</security-role>
</web-app>
So is there anything I did not pay attention to or I just cannot inject named bean but ejb into javax-rest class.

Could not load user defined filter in web.xml: com.xxx.CORSFilter

I have a SpringBoot application running on WebLogic Server Version: 12.2.1.3.0
When I define a custom servlet Filter its working fine on Embedded Tomcat. However, when i deploy my application as a war file to wlserver it throws following error after each request. What am i missing here?
<Could not load user defined filter in web.xml: com.thy.bwsadmin.CORSFilter.
java.lang.AbstractMethodError
at weblogic.servlet.internal.FilterManager$FilterInitAction.run(FilterManager.java:400)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:328)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.FilterManager.initFilter(FilterManager.java:130)
at weblogic.servlet.internal.FilterManager.loadFilter(FilterManager.java:92)
at weblogic.servlet.internal.FilterManager.preloadFilters(FilterManager.java:72)
at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1928)
at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3106)
at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1843)
at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:884)
at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)
at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:233)
at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:228)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:78)
at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:52)
at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:752)
at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:262)
This is the content of my web.xml file
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>MWSAdminService</display-name>
<filter>
<filter-name>CORSFilter</filter-name>
<filter-class>com.sample.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I am setting servlet dependency as provided to prevent jar conflicts.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
This is my Filter class.
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.thy.bwsadmin.service.SecurityUserService;
#Component
#Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {
#Autowired
SecurityUserService securityUserService;
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
boolean isAuthenticated = authenticateUser(request.getHeader("identity_no"), request.getRequestURI());
if (isAuthenticated) {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
} else {
response.sendError(HttpServletResponse.SC_OK, "401");
}
}
private boolean authenticateUser(String userId, String requestURI) {
if (Util.isNotEmpty(userId)
&& securityUserService.isAuthorizedForEndpoint(userId.trim(), requestURI)) {
return true;
}else{
return false;
}
}
}
As a solution i tried to remove the filter definitions in web.xml file and registered my filter as a bean configuration since this is a SpringBoot application. I also removed #Component and #Order annotations from my filter.
But the result was the same as above. It is still working on Tomcat but not in Weblogic. Here is the code for filter config bean.
#Configuration
public class Filters {
#Bean
public FilterRegistrationBean<CORSFilter> loggingFilter() {
FilterRegistrationBean<CORSFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CORSFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
Your servlet api provided by weblogic is probably old version and your filter class needs to override init method.
Add below code at your filter class;
#Override
public void init(FilterConfig filterConfig) throws ServletException {};
At new versions of servlet api, filter class has default empty init method.

Jersey filter registration via web xml not working

I have a filter which should validate Ids of incoming requests if the resource it is send to is annotated with IdValidation.
I tried to add this filter in the web xml as described in this tutorial. However the filter is not invoked when testing a method with the IdValidation annotation.
#Provider
#IdValidation
public class IdValidationFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
this.requestContext = requestContext;
MultivaluedMap<String, String> map = requestContext.getUriInfo().getPathParameters();
if (map.containsKey("someId")) {
// Do some validation and abort if nessecary
}
}
}
The interface I use to add this filter.
#NameBinding
#Retention(RetentionPolicy.RUNTIME)
public #interface IdValidation {}
The web xml. I tried without the provider classnames at first because I think this is not necessary since the filter is in the same package, but this didn't work either.
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>my.package.IdValidationFilter</param-value>
</init-param>
</servlet>
try this code -
import java.io.IOException;
import java.lang.annotation.Annotation;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
#Provider
public class IdValidationFilter implements ContainerRequestFilter {
#Context
private ResourceInfo resourceInfo;
#Context
private HttpServletRequest request;
#Override
public void filter(final ContainerRequestContext requestContext) throws IOException {
for (Annotation annotation : resourceInfo.getResourceMethod().getDeclaredAnnotations()) {
if (IdValidation.class == annotation.annotationType()) {
this.requestContext = requestContext;
MultivaluedMap<String, String> map = requestContext.getUriInfo().getPathParameters();
if (map.containsKey("someId")) {
// Do some validation and abort if nessecary
}
}
}
}
}
If you want to validate a parameter, I suggest you should have a look at Jersey's Bean Validation support.

How to integrate Cross Origin Resource Sharing with Spring MVC 4.0.0 RESTful Webservice

I have a Simple Web Service returning JSON data.
The User Class (com.bargadss.SpringService.Domain) is The POJO class containing
user_ID, firstName, lastName, eMail
The UserService class (com.bargadss.SpringService.DAO) two major operation
getAllUser() -> Queries the DB to Select all Users from User Table and returns List{User}
getUserById(int user_ID) -> Queries the DB to Select a specific user based on ID
The SpringServiceController (com.bargadss.SpringService.Controller) is as follows :
package com.bargadss.SpringService.Controller;
import java.util.List;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.bargadss.SpringService.DAO.UserService;
import com.bargadss.SpringService.Domain.User;
#RestController
#RequestMapping("/service/user/")
public class SpringServiceController {
UserService userService=new UserService();
#RequestMapping(value = "/{id}", method = RequestMethod.GET,headers="Accept=application/json")
public User getUser(#PathVariable int id) {
User user=userService.getUserById(id);
return user;
}
#RequestMapping(method = RequestMethod.GET,headers="Accept=application/json")
public List<User> getAllUsers() {
List<User> users=userService.getAllUsers();
return users;
}
}
The ListUserController (com.bargadss.SpringService.Controller) is as follows :
package com.bargadss.SpringService.Controller;
import java.util.LinkedHashMap;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import com.bargadss.SpringService.Domain.User;
#Controller
public class ListUserController {
#RequestMapping("/listUsers")
public ModelAndView listUsers() {
RestTemplate restTemplate = new RestTemplate();
String url="http://localhost:8080/SpringServiceWithRESTAndJSONExample/service/user/";
List<LinkedHashMap> users=restTemplate.getForObject(url, List.class);
return new ModelAndView("listUsers", "users", users);
}
#RequestMapping("/dispUser/{userid}")
public ModelAndView dispUser(#PathVariable("userid") int userid) {
RestTemplate restTemplate = new RestTemplate();
String url="http://localhost:8080/SpringServiceWithRESTAndJSONExample/service/user/{userid}";
User user=restTemplate.getForObject(url, User.class,userid);
return new ModelAndView("dispUser", "user", user);
}
}
The CorsFilter (com.bargadss.CORS) is as follows :
package com.bargadss.CORS;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
public class CorsFilter extends OncePerRequestFilter{
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1800");//30 min
}
filterChain.doFilter(request, response);
}
}
The web.xml is as follows :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>SpringServiceWithRESTAndJSONExample</display-name>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>/WEB-INF/jsp/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>cors</filter-name>
<filter-class>com.bargadss.CORS.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
The Web Service when being invoked by AngularJS from another Web Server returns Error referring to Cross Origin Resource Sharing problem !!!
What Changes must be performed in the Controller side to eliminate the error ?
Is there any changes necessary to be done at the AngularJS side to avoid this situation ?
Check the cors-filter
Download cors-filter-2.1.2.jar and java-property-utils-1.9.1.jar.
mvn dependency
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>java-property-utils</artifactId>
<version>1.9.1</version>
</dependency>
and in web.xml
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Categories

Resources