Authorize requests using tokens stored in database - java

I am try to implement authentication filter in spring project. I have tokens stored for customers in database. Currently the authorization happens separately in each API.
Here is the current version of the api:
#CrossOrigin
#RequestMapping(value="/thirdParty", method=RequestMethod.GET)
private void getThirdPartyOffers(HttpServletRequest request, HttpServletResponse response){
response.setHeader("Access-Control-Allow-Origin", "*");
String authToken = request.getHeader(AUTHORIZATION);
if (null != authToken) {
Customer customer = getCustomer(authToken, sessionFactory);
if (null != customer) {
JsonObject responseObject = new JsonObject();
Integer cityId=-1;
if(customer.getDeliveryAddress()!=null &&customer.getDeliveryAddress().getCity()!=null){
cityId=customer.getDeliveryAddress().getCity().getId();
}else if(customer.getLocality()!=null){
cityId= customer.getLocality().getCity().getId();
}else if(customer.getArea()!=null){
cityId= customer.getArea().getCity().getId();
}
JsonArray offers = promotionOfferUtils.getThirdPartyOfferList(customer, cityId);
responseObject.add("offers", offers);
responseObject.addProperty(ERROR, false);
sendResponse(response,HttpServletResponse.SC_OK,responseObject);
return;
}else{
sendResponse(response, HttpServletResponse.SC_UNAUTHORIZED, ERROR,
AUTHORIZATION_FAILED);
}
}else {
sendResponse(response, HttpServletResponse.SC_UNAUTHORIZED, ERROR,
AUTHORIZATION_FAILED);
}
}
The final api should be like this:
#CrossOrigin
#RequestMapping(value = "/thirdParty", method = RequestMethod.GET)
private void getThirdPartyOffers(HttpServletRequest request, HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Origin", "*");
String customerId = response.getHeader("customerId");
Customer customer = getCustomer(sessionFactory, customerId);
JsonObject responseObject = new JsonObject();
Integer cityId = -1;
if (customer.getDeliveryAddress() != null && customer.getDeliveryAddress().getCity() != null) {
cityId = customer.getDeliveryAddress().getCity().getId();
} else if (customer.getLocality() != null) {
cityId = customer.getLocality().getCity().getId();
} else if (customer.getArea() != null) {
cityId = customer.getArea().getCity().getId();
}
JsonArray offers = promotionOfferUtils.getThirdPartyOfferList(customer, cityId);
responseObject.add("offers", offers);
responseObject.addProperty(ERROR, false);
sendResponse(response, HttpServletResponse.SC_OK, responseObject);
return;
}
I am now trying to authenticate using a filter.Here I have created the required filter.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// invoked when a matching request sent to the server
// used to intercept the request and transform the response
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Access-Control-Allow-Headers", "origin, content-type, Authorization, accept, x-requested-with, IS_UPDATED");
httpResponse.setHeader("Access-Control-Max-Age", "60"); // seconds to cache preflight request --> less OPTIONS traffic
httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
httpResponse.setHeader("Access-Control-Allow-Origin", "*");
Customer customer;
try
{
if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) {
httpResponse.setStatus(HttpServletResponse.SC_OK);
return;
} else {
String url = ((HttpServletRequest) request).getRequestURL().toString();
String endUrlPath = url.split("/").length > 1 ? url.split("/")[url.split("/").length - 1] : "";
if (!endUrlPath.equalsIgnoreCase("login") && !endUrlPath.equalsIgnoreCase("forgotPasswordSendOtp") &&
!endUrlPath.equalsIgnoreCase("changePasswordInForgotPassword") && !endUrlPath.equalsIgnoreCase("verifyUserOTP")) {
String authToken = httpRequest.getHeader("Authorization");
customer = getCustomer(authToken,sessionFactory);
if (customer == null) {
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
httpResponse.addHeader("customerId", Integer.toString(customer.getId()));
}
}
} catch (Exception ex) {
httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
chain.doFilter(request, response);// invokes next filter in the chain
}
The problem now is that the sessionFactory object is null at this point and I am unable to access database to get the customer.
I am unable to figure out how to get access to sessionFactory when the startup is incomplete?

Related

Get session object from one controller method to another

Can I know how can I get the session object which I have set in one controller method to another controller method.
Code:
public ResponseEntity<String> generateId(#RequestBody IdCreationVO idCreationVO, HttpServletRequest request) throws CareBusinessServiceException {
log.info("In Controller Method: generateId : "+idCreationVO.toString());
if(null !=idCreationVO && null == idCreationVO.getIsSupressCommunication()) {
HttpSession session = request.getSession();
session.setAttribute(AmhiConstants.COMMUNICATION_SUPPRESSED, idCreationVO.getIsSupressCommunication());
log.info("session object communication: "+ idCreationVO.getIsSupressCommunication());
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity(idCreationService.generateId(idCreationVO), headers,
HttpStatus.OK);
}
public ResponseEntity<String> updateAuthorizationDetails(#RequestBody AuthorizationVO authorizationVO, HttpServletRequest request) throws CareBusinessServiceException {
String communicationSuppressed = null;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
String authNbrResponse = idCreationService.updateAuthorizationDetails(authorizationVO);
if(null != request.getSession()) {
communicationSuppressed = (String) request.getSession().getAttribute(AmhiConstants.COMMUNICATION_SUPPRESSED);
log.info("communicationSuppressed value: "+ communicationSuppressed);
}
/** This method is get triggered from controller as the communication registered functionality get excecuted before updateAuthorizationDetails ends **/
if (null != authNbrResponse && communicationSuppressed.equals(AmhiConstants.CONSTANT_Y)) {
String[] authorizationNumber = authNbrResponse.split(":");
if (authorizationNumber.length > 1) {
if (authorizationNumber[1].equalsIgnoreCase(AmhiConstants.STATUS_SUCCESS)) {
idCreationService.triggercommunicationAfterAuthorizationRegistered(authorizationNumber[0]);
}
}
}
return new ResponseEntity(authNbrResponse, headers,
HttpStatus.OK);
}
As per requirement I need the value which been sent in generateId method to be get used in updateAuthorizationDetails method.
Can I know the above code implementation works fine in user session?
session.setAttribute and session.getAttribute methods should work.
But the problem seems to be in the if condition:
if(null !=idCreationVO && null == idCreationVO.getIsSupressCommunication()) {
HttpSession session = request.getSession();
session.setAttribute(AmhiConstants.COMMUNICATION_SUPPRESSED, idCreationVO.getIsSupressCommunication());
log.info("session object communication: "+ idCreationVO.getIsSupressCommunication());
}
It checks whether idCreationVO.getIsSupressCommunication() is null and then sets it to the session. In other words, it only sets the variable to the session when it is null.
I guess you mean:
if(null !=idCreationVO && null != idCreationVO.getIsSupressCommunication()) {
HttpSession session = request.getSession();
session.setAttribute(AmhiConstants.COMMUNICATION_SUPPRESSED, idCreationVO.getIsSupressCommunication());
log.info("session object communication: "+ idCreationVO.getIsSupressCommunication());
}

I want to used lang to mark languages.In the process of authentication,This parameter is lost

http://localhost:8080/auth/login?lang=en I want to used lang to mark languages.In the process of authentication,This parameter is lost.
I read the source code.
LoginUrlAuthenticationEntryPoint.commence
```java
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
String redirectUrl = null;
if (useForward) {
if (forceHttps && "http".equals(request.getScheme())) {
// First redirect the current request to HTTPS.
// When that request is received, the forward to the login page will be
// used.
redirectUrl = buildHttpsRedirectUrlForRequest(request);
}
if (redirectUrl == null) {
String loginForm = determineUrlToUseForThisRequest(request, response,
authException);
if (logger.isDebugEnabled()) {
logger.debug("Server side forward to: " + loginForm);
}
RequestDispatcher dispatcher = request.getRequestDispatcher(loginForm);
dispatcher.forward(request, response);
return;
}
}
else {
// redirect to login page. Use https if forceHttps true
redirectUrl = buildRedirectUrlToLoginPage(request, response, authException);
}
redirectStrategy.sendRedirect(request, response, redirectUrl);
}
```
Rewrite redirectUrl
AbstractAuthenticationFilterConfigurer
java
private void addAuthenticationEntryPoint(HttpSecurity http, OAuth2SsoProperties sso)
throws Exception {
...
exceptions.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint(sso.getLoginPath()),
preferredMatcher);
...
}
That need to Overwrite too much code.
I wonder if I didn't find a suitable existing configuration to solve this problem.
solved by Filter
save the msg in session

How can i restrict the request from the unauthorized users (url's)?

Here my problem is that in my spring project totally 3 Jsp pages are available.
home page
register page
register success full page
When i type url for the home page in a browser, i am getting home page.and inside one hyperlink is available to register data. automatically when i click on that link it will go to the register page.then after it will go to the register success full page.
So finally my problem is that when i gave home page url in browser, homepage comes and also if i give register page url it will go to the register page with out touches the home page. but actually i want to access the register page through home page.
Use a token like JWT, set the token on access through Home page. Use a MVC Interceptor or a Filter and check that the token is present in the request before presenting the register page . If token not present redirect to home page.
Spring Security allows user's to access the url's as per authorization.
You can specify, which user has access to which url, if the user is not authorized then redirect to home page or just say access denied.
Please refer the spring security doc.it might help you.
You can simply create an authentication filter and specify on which methods you need to call this filter, for example, you want only an authorised user to access the downloadDoc api. Here is the sample code for this:
#WebFilter(urlPatterns = { "/getDocs", "/downloadDoc", "/updateStatus", "/submitApplication", "/login", "/logout",
/*"/requestDocuments", "/sendEmailRequest"*/"/getAllApplication", "/getApplicationDetails",
"/getAccountDetails" })
public class AuthenticationFilter implements Filter {
private static Logger logger = Logger.getLogger(AuthenticationFilter.class);
#Autowired
private UserVerificationService userVerificationService;
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("checking token in filter");
HttpServletRequest request = (HttpServletRequest) arg0;
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
DocVerificationRequestWrapper myRequestWrapper = new DocVerificationRequestWrapper(request);
String body = myRequestWrapper.getBody();
String serviceName = request.getServletPath();
logger.info("serviceName = " + serviceName);
Token token = null;
try {
JSONObject jsonObj = new JSONObject(body);
logger.info(jsonObj);
if (jsonObj != null) {
JSONObject tokenObj = (JSONObject) jsonObj.get("token");
Gson gson = new Gson();
token = gson.fromJson(tokenObj.toString(), Token.class);
String clientName = request.getHeader("clientName");
logger.info("clientName = " + clientName);
if (null != token) {
if (userVerificationService == null) {
ServletContext servletContext = request.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
userVerificationService = webApplicationContext.getBean(UserVerificationService.class);
}
ClientResponse cr = userVerificationService.verifyUser(token, clientName, serviceName);
String verStatus = cr != null ? cr.getStatus() : null;
logger.info("verStatus = " + verStatus);
if (verStatus != null && verStatus.equalsIgnoreCase("success")) {
chain.doFilter(myRequestWrapper, response);
} else {
logger.error("Invalid token");
cr.setStatus("failure");
cr.setMessage("Invalid Token");
cr.setErrorCode("157");
cr.setToken(token);
response.getOutputStream().write(new ObjectMapper().writeValueAsBytes(cr));
// ((HttpServletResponse) response).sendError(157, "Invalid Token");
}
} else {
logger.error("token missing.");
ClientResponse cr = new ClientResponse();
cr.setStatus("failure");
cr.setMessage("Missing Token");
cr.setErrorCode("158");
response.getOutputStream().write(new ObjectMapper().writeValueAsBytes(cr));
// ((HttpServletResponse) response).sendError(158, "Token Missing");
}
}
} catch (JSONException e) {
logger.error("exception in authetication filter " + e);
}
}
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}

Attribute set in a filter can't be retrieved using $request.getAttribute("attributeName")

we implemented some servlets, JSPs and filters and everything was
working fine so far. I wan't to track one requestURL for next 2-3
requests and I can't save this in session as we are using session for
login purpose. But when we tried to set an attribute in the request
object and read it from within a JSP, we always get null values.
In the filter class, we do the following:
String url = ((HttpServletRequest)req).getRequestURL().toString();
if(url.contains("asc/ascHome")){
HttpServletRequest request = (HttpServletRequest) req;
request.setAttribute("OriginURL", "AscHome");
}
chain.doFilter(request, response);
> In our login.jsp, we are using the following code to retrieve the
> attribute:
String originURL = request.getAttribute("OriginURL").toString();
> Is there anything we're missing?
>
> Filter is as below,
public class SessionAlertFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
throws IOException, ServletException {
HttpServletResponse httpResp = (HttpServletResponse) resp;
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpSession session = httpReq.getSession();
String str_session_id = session.getId();
//System.out.println(" session.getMaxInactiveInterval() :"+session.getMaxInactiveInterval());
long currTime = System.currentTimeMillis();
//long expiryTime = currTime + (2*60 * 1000); //25 minutes considering 30 minutes is session timeout
long expiryTime = currTime + ((session.getMaxInactiveInterval() * 1000) - (5*60*1000));
Cookie cookie = new Cookie("serverTime", "" + currTime);
cookie.setPath("/");
httpResp.addCookie(cookie);
//SessionObj session_obj = (SessionObj) session.getAttribute("session_obj");
if (str_session_id != null) {
//System.out.println("session id2------"+str_session_id+" expiryTime: "+expiryTime);
//showTime(expiryTime);
cookie = new Cookie("sessionExpiry", "" + expiryTime);
} else {
cookie = new Cookie("session id2------"+str_session_id+" sessionExpiry", "" + currTime);
//showTime(expiryTime);
//System.out.println("currTime: "+currTime);
}
cookie.setPath("/");
((HttpServletResponse) resp).addCookie(cookie);
String url = ((HttpServletRequest)req).getRequestURL().toString();
System.out.println("In Filter.... URL : "+url);
if(url.contains("asc/AscHome.jsp")){
req.setAttribute("OriginURL", "Register_Call");
}
filterChain.doFilter(req, resp);
//checkCookie(httpReq);
}

Upgrading from CXF 2.7 to CXF 3.0

I am trying to upgrading one of the code bases to CXF 3.0 and some of the classes are deprecated and trying to upgrade the dependencies.
#Override
public Response handleResponse(Message m, OperationResourceInfo ori,
Response response) {
if (response.getStatus() == Response.Status.OK.getStatusCode()){
if (response.getHeaderString("my_header") == null){
Message inMessage = m.getExchange().getInMessage();
String headerKey = getMyHeaderKey(inMessage);
if (headerKey != null){
AbstractResponse entityResponse = (AbstractResponse) response.getEntity();
response = generateResponse(entityResponse, inMessage, false);
}
}
}
return response;
}
private Response generateResponse(AbstractResponse ar, Message msg, boolean isConflict){
ResponseBuilder responseBldr;
if (isConflict){
responseBldr = Response.status(Status.CONFLICT);
}
else{
responseBldr = Response.ok(ar);
}
responseBldr.header("header1", "true");
HttpServletRequest request = (HttpServletRequest) msg.get(AbstractHTTPDestination.HTTP_REQUEST);
String retryId = request.getHeader("header2");
if (retryId != null){
responseBldr.header("header2", retryId);
}
return responseBldr.build();
}
I tried to use ContainerRequest/Response filters, but couldn't find how can I set the response
#Override
public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
Message m = JAXRSUtils.getCurrentMessage();
containerResponseContext.getStatus();
if (containerResponseContext.getStatus() == Response.Status.OK.getStatusCode()){
if (containerResponseContext.getHeaderString("my_header") == null){
Message inMessage = m.getExchange().getInMessage();
String headerKey = getMyHeaderKey(inMessage);
if (headerKey != null){
AbstractResponse entityResponse = (AbstractResponse) containerResponseContext.getEntity();
response = generateResponse(entityResponse, inMessage, false); //how do I do this with CXF 3.0?
}
}
}
}
Please refer JAX-RS 2.0 Filter here which says new filters ContainerRequestFilter and ContainerResponseFilter have been introduced. Here is an example below which in short does all the actions you were trying to achieve.
public class KPFilter implements ContainerResponseFilter {
private Logger LOG = LoggerFactory.getLogger(KPFilter.class);
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
if(responseContext.getStatus()== Status.OK.getStatusCode()){
final String myHeader = requestContext.getHeaderString("myHeader");
if(myHeader !=null && myHeader.equals("kp-header")){
responseContext.getHeaders().add("resHeader", myHeader+"-res");
}else{
responseContext.setEntity("An erro occured");
responseContext.setStatus(500);
}
}else{
LOG.info("Status is not OK, its {}", responseContext.getStatus());
}
}
}
And the cxf configuration file
<jaxrs:providers>
<bean class="com.xxxxx.xxxxx.KPFilter" />
</jaxrs:providers>

Categories