getting and setting cookie spring mvc - java

I am using #requestbody and #responsebody annotations for my authentication method using Spring MVC. I want to know how can I get and set cookies in spring mvc.. I need to store username and password in my cookie, which I am getting through the requestbody. Also want to know how can I get this set cookie in the browser, the next time the user logs in. Also does the browser sends the cookie automatically with the request body ? To be specific I don't want to go for Spring Security Remember me option. I am new to spring framework so an example code would be highly appreciated.
Ajax Code in JS:
var ajaxOptions = {
type: callType,
url: serviceCompleteUrl,
/* Add if required.
dataType: returnType */
async: false,
success: function(data, status, xhr) {
/*
* TODO: See if this is required
if (xhr.status == 200) {
*/
ajaxSuccess = true;
serviceResponse = data;
/*
}
*/
},
in the service I am just returning the object which will be mapped onto the serviceResponse and could be used by JS..
Sample code for service :
#RequestMapping("/login")
public #ResponseBody LoginObject Login(#RequestBody LoginParameter request)
{
/* Code */
return LoginObject;
}
This is how I am returning the object from the service, which is then catched by the serviceresponse in js..

Never store passwords (even encrypted) in Cookies. To implement the Remember me functionality you desire, you follow this answer
Update:
You need the logic for saving data in cookies on JS side. After the call to the service returns LoginObject, use some JS or jQuery code (like document.cookie="key=" + value;) to store data in cookies.

Related

Axios get request from React to Spring Boot application returns Network Error

I have a SpringBoot application with a #Controller that accepts a getRequest to localhost:8080/all and returns JSON. I have entered this domain in the browser and see the returned JSON.
However, when I attempt to hit this url with an Axios get request from my React app (which is running locally), rather than returning the JSON data, it returns the following error:
Network Error at createError (http://localhost:3000/static/js/bundle.js:1634:15) at XMLHttpRequest.handleError (http://localhost:3000/static/js/bundle.js:1170:14)
I checked Chrome's network tab for the get request and it doesn't return anything for the preview or response, but does indicate:
Request URL: https://localhost:8080/all
Referrer Policy: no-referrer-when-downgrade
in the Headers section.
Both applications are running locally and when I try a different axios get request (for a different API) it returns the JSON successfully. How can I successfully return JSON from my Spring Boot application?
The React setup for the API call is:
componentDidMount() {
axios.get('https://localhost:8080/all')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
And the controller action in the Spring Boot app is:
#RestController
public class UserController {
#Autowired
UserJDBCDao dao;
#GetMapping(path="/all")
public #ResponseBody Iterable<User> getAllUsers() {
// This returns a JSON or XML with the users
return dao.findAll();
}
}
After checking the Spring Boot error log it indicated:
java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens
So I changed https to http and the request worked. I'm not sure if this is the most secure way, so someone else might have a better solution.

Spring Interceptor which matches user id with a token

I am porting a REST web application from struts 2 to spring 5 (w/ spring boot). In our Api, we pass three attributes in each request (names are anonymised):
uuid, token, bananaId
In the backend we look for a user in a database with uuid, and check if it has token in it's list of tokens. If it has, the request is authorized and we add bananaId to the user's set of bananas.
I can do checking in each request individually -- and this is how it was implemented in struts. How to make a spring interceptor which would do this for each request (excluding a login action)?
I have successfully configured HandlerInterceptorAdapter, but I'm stuck on what to do next. Which approach is the best in this case?
EDIT: pseudo code of a controller
#RequestMapping("/getFoo")
public GetFooRsponse getFoo(#RequestBody Request request) {
Optional<User> user = getUser(request.getUuid());
if (user.isPresent() && user.get().getGcmTokens().contains(request.getGcmToken())){
user.get().getBanIds().add(request.getbanId());
// handle request
} else {
// unauthorized?
}
}
A solution which would be fine:
#RequestMapping("/getFoo")
#CheckGcmToken
public GetFooRsponse getFoo(#RequestBody UserRequest request) {
// handle request
}

Java webapp responding the source code of my login page

I have a java web application which publish a service that returns an object in JSON format, and I have another java web app just to consume that service through a JSONP call and show the response. In my local machine it's working fine, but now that I want to test it in a web environment (Layershift in my case), I can't get the JSON object. I don't see any errors on Chrome developer tools, but when I look into the Response tab (in Network option) I see the source code of the login page of my application. Let me show you the my code
Controller with the service:
#RestController
public class MyController {
#RequestMapping(value="/myservice/get/{somevar}")
public MappingJacksonValue getMyObject (#RequestParam String callback, #PathVariable String somevar, HttpServletRequest request, HttpServletResponse response) {
MyObject obj = new MyObject();
//some logic
MappingJacksonValue value = new MappingJacksonValue(obj);
value.setJsonpFunction(callback);
return value;
}
}
javascript code for call the service:
$.fn.callWithJsonP = function(somevar) {
var url = "/myservice/get/" + somevar + "?callback=myCallback";
$.getJSON(url, function(data) {
if (data.value.status == "OK") {
//shows the data contained
}
});
}
Apache configuration (added to avoid CORS error), present in both applications
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
Header always unset X-Frame-Options
This is working perfectly on muy local machine (except for the Apache, I don't use it locally), but as I said, on a web environment I receive the source code of my login page. In the Headers tab I can see the headers added in Apache, and the status code of the response is OK, any clues about what's goin on?
Kind regards
UPDATEI've removed the Apache web server, and even tested the web service with Postman (meaning, no second application), and still the same result. I've tried changing #RestController for #Controller and returning an instance of MyObject (instead of MappingJacksonValue), with no results, please help me
I am probably way off here, but is it possible that you have a servlet filter or other part of your web app config that is routing your get request to your login page before your REST framework is able to map it to your endpoint? I use Jersey for this usually, so I am unfamiliar with Spring's RestController, but I assume it is doing similar thing - routes URLs that match to the java code. If you are seeing login page in response it sounds like something is interfering and trying to force user to login before Spring directs to your endpoint method.
It seems like you have a fallback set in your server, maybe configured for a single page application. This is normally used for routing with HTML5 mode using routers like angular's.
you are getting the login page code as response because the login is failed and you are redirected to the same page.. so before calling the service first you need to do the authentication and then by using the authentication token call the service..

How to approach this authentication mechanism in Jersey

I am new to Jersey REST Framework , so please excuse if this is a dumb question .
I am using Tomcat with Hibernate and Jersey REST Webservices.
I have got set of HTML pages in my Web APP
login.html
dealer.html
sales.html
I dont want the User to access the HTML pages directly other than login.html
So to resolve this issue , when submit is pressed , under login.html call
following call is made to the backend
#Path("/webchecklogin")
public class WebLoginCheck {
#Context
private HttpServletResponse response;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public String getData(LoginInfo loginInfo ) throws JSONException,ClassNotFoundException, SQLException
{
String ID = loginInfo.getID();
String email = loginInfo.getEmail();
// validate this values with Database and if successfully logged in , stored them in session AND cookies also
}
}
And inside dealer.html and sales.html , on page ready i am calling a service as shown below
var checkcallajax = $.ajax({
type: 'GET',
url: url + '/ORIENT/orn/checkifuserloggedin',
jsonpCallback: 'jsonCallback',
success: function(response) {
}
})
#Path("/checkifuserloggedin")
public class CheckIfUserLoggedIn {
#Context
private HttpServletRequest request;
#GET
#Consumes(MediaType.APPLICATION_JSON)
#Produces("application/json")
public String checkIfUserLoggedIn() throws JSONException,ClassNotFoundException, SQLException
{
// On what basis , should i check wheher the USER is logged or NOT
// I tried storing data with Session and cookies , but i am unable to retrive them here
//return true or false
// based on true or false , i am redireting user to appropiate page
}
}
Could anybody please let me know how to approach this
RestFUL web services are supposed to be stateless, so in theory, you could send the credential with every request, and that would be totally stateless from the "server point of view"
Most will find this cumbersome, resource intensive, and storing credentials on the client is somewhat bad from a security point.
The alternative approach could be that your login method returns a token, that needs to be re-sent (in a header maybe) to the server with every request.
The client must know how to store it (session cookie? on the domain
serving html, if you are in a CORS scenario)
The server must know how to validate the token.
On top of it, the validation of the Token can be done in a JaxRS Filter... before reaching your service entry point. And even better, this filter could add roles to the request context, so you can the use the #RolesAllowed annotation with your services.
I "very personnally" avoid relying on the javax.servlet.Session, as this is fundamentally stateful. But, you should be able to do it, given that the clients stores the jSessionId (other other cookie name) in a session cookie. If it does not work, you might have CORS or other domain specific problem, preventing the client from storing and returning this cookie automatically.
Hope it helps.

Passing $routeParams from angularjs to spring-MVC controller

This is what I have in my AngularJs controller
.when("/M:topicId", {templateUrl: "Mu", controller: "conMFs"})
app.controller('conMFs',function($scope,$routeParams){
$scope.otherId = $routeParams.topicId;
});
This is my Spring Controller
#RequestMapping(value="/controlerM", method = RequestMethod.GET)
public ModelAndView controlerM(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView model = null;
session=request.getSession(true);
user = (User) session.getAttribute("user");
List<ends1> ends=(List<ends1>) ifriendlistservice.getends(user.getId(),5);
session.setAttribute("MutualFriends", MutualFriends);
model = new ModelAndView("ends");
return model;
I am able to fetch the topicId from my AngularJS page in AngularJS controller (with $scope.otherId), however I am unable to pass this value to my Spring controller, from where I am redirecting to new page.
How should I do this?
.when("/M:topicId", {templateUrl: "Mu", controller: "conMFs"})
app.controller('conMFs',function($window){
$window.location.reload();
});
Then server app gets topicId from request's url. You also need to have $locationProvider.html5Mode enabled.
How should I do this?
You shouldn't. Angular's off-hour job is to not let server apps to reload the page. The code above is quick-and-dirty, it can be ok only if you're in the middle of Angular integration into existing project, but the time-frame requires you to partially rely on old code base.
If you really need to make a redirect (e.g. to external page), make an AJAX request, put topicId and whatever there, get redirect url in response, redirect with $window.location.href.
I'm barely familiar with Spring, but the above applies to any server-side application.
Thanks estus,
Issue seems to be resolved...
I had created 2 controller in Spring, One for setting parameter through ajax , and other for redirection.

Categories